udev-builtin-net_id.c revision a4bbef099209d4e3bccd913cd30da536f8971064
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/***
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering This file is part of systemd.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering Copyright 2012 Kay Sievers <kay@vrfy.org>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering systemd is free software; you can redistribute it and/or modify it
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering under the terms of the GNU Lesser General Public License as published by
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering (at your option) any later version.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering systemd is distributed in the hope that it will be useful, but
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering Lesser General Public License for more details.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering You should have received a copy of the GNU Lesser General Public License
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering***/
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/*
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering * Predictable network interface device names based on:
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering * - firmware/bios-provided index numbers for on-board devices
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * - firmware-provided pci-express hotplug slot index number
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * - physical/geographical location of the hardware
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * - the interface's MAC address
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering *
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering *
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering * Two character prefixes based on the type of interface:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * en -- ethernet
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * wl -- wlan
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering * ww -- wwan
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering *
0d39fa9c69b97a2ceb156053deef69c0866c2b97Lennart Poettering * Type of names:
c004493cdefc1f43a3956ca529e8070f8d70be56Lennart Poettering * o<index> -- on-board device index number
a09abc4ae0bdc0200324eaa0416f23ff2170ec4eLennart Poettering * s<slot>[f<function>][d<dev_id>] -- hotplug slot index number
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * x<MAC> -- MAC address
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poettering * [P<domain>]p<bus>s<slot>[f<function>][d<dev_id>]
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * -- PCI geographical location
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * -- USB port number chain
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering *
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering * All multi-function PCI devices will carry the [f<function>] number in the
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * device name, including the function 0 device.
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering *
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * When using PCI geography, The PCI domain is only prepended when it is not 0.
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering *
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * For USB devices the full chain of port numbers of hubs is composed. If the
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * name gets longer than the maximum number of 15 characters, the name is not
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * exported.
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * The usual USB configuration == 1 and interface == 0 values are suppressed.
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering *
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * PCI ethernet card with firmware index "1":
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering * ID_NET_NAME_ONBOARD=eno1
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering *
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * PCI ethernet card in hotplug slot with firmware index number:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_MAC=enx000000000466
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_PATH=enp5s0
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_SLOT=ens1
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering *
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * PCI ethernet multi-function card with 2 ports:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_MAC=enx78e7d1ea46da
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_PATH=enp2s0f0
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_MAC=enx78e7d1ea46dc
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_PATH=enp2s0f1
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering *
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * PCI wlan card:
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering * ID_NET_NAME_MAC=wlx0024d7e31130
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_PATH=wlp3s0
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering *
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * USB built-in 3G modem:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_MAC=wwx028037ec0200
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_PATH=wwp0s29u1u4i6
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering *
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * USB Android phone:
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_MAC=enxd626b3450fb5
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * ID_NET_NAME_PATH=enp0s29u1u2
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering#include <stdio.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <stdlib.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <stdarg.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <unistd.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <string.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <errno.h>
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering#include <net/if.h>
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering#include <linux/pci_regs.h>
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering#include "udev.h"
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering#include "fileio.h"
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmekenum netname_type{
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering NET_UNDEF,
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen NET_PCI,
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen NET_USB,
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen NET_BCMA,
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering};
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstruct netnames {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering enum netname_type type;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering uint8_t mac[6];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering bool mac_valid;
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering struct udev_device *pcidev;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char pci_slot[IFNAMSIZ];
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering char pci_path[IFNAMSIZ];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char pci_onboard[IFNAMSIZ];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering const char *pci_onboard_label;
44b601bc79e46722bc0f0862ee0ce34a2284ef11Lennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering char usb_ports[IFNAMSIZ];
25d042e81516246b1ebf706a57c47ac19abb0b8aLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char bcma_core[IFNAMSIZ];
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering};
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering/* retrieve on-board index number and label from firmware */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringstatic int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering const char *index;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int idx;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering /* SMBIOS type 41 -- Onboard Devices Extended Information */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!index)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering index = udev_device_get_sysattr_value(names->pcidev, "index");
25d042e81516246b1ebf706a57c47ac19abb0b8aLennart Poettering if (!index)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -ENOENT;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering idx = strtoul(index, NULL, 0);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (idx <= 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -EINVAL;
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/* read the 256 bytes PCI configuration space to check the multi-function bit */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic bool is_pci_multifunction(struct udev_device *dev) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char filename[256];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering FILE *f = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char config[64];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering bool multi = false;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev));
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering f = fopen(filename, "re");
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering if (!f)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto out;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (fread(&config, sizeof(config), 1, f) != 1)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto out;
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering /* bit 0-6 header type, bit 7 multi/single function device */
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering multi = true;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringout:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if(f)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering fclose(f);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return multi;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringstatic int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering struct udev *udev = udev_device_get_udev(names->pcidev);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering unsigned int domain;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering unsigned int bus;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering unsigned int slot;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering unsigned int func;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering unsigned int dev_id = 0;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering size_t l;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char *s;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering const char *attr;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering struct udev_device *pci = NULL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char slots[256];
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering DIR *dir;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering struct dirent *dent;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char str[256];
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int hotplug_slot = 0;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int err = 0;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%d", &domain, &bus, &slot, &func) != 4)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -ENOENT;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering /* kernel provided multi-device index */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering attr = udev_device_get_sysattr_value(dev, "dev_id");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (attr)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering dev_id = strtol(attr, NULL, 16);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* compose a name based on the raw kernel's PCI bus, slot numbers */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s = names->pci_path;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l = sizeof(names->pci_path);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (domain > 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "P%d", domain);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "p%ds%d", bus, slot);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (func > 0 || is_pci_multifunction(names->pcidev))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "f%d", func);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (dev_id > 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "d%d", dev_id);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (l == 0)
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering names->pci_path[0] = '\0';
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* ACPI _SUN -- slot user number */
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!pci) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering err = -ENOENT;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering goto out;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek }
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek dir = opendir(slots);
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek if (!dir) {
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek err = -errno;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek goto out;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek }
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering int i;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering char *rest;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *address;
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen if (dent->d_name[0] == '.')
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering continue;
9a7800af088cc013573310504ae76e325d44d4b4Zbigniew Jędrzejewski-Szmek i = strtol(dent->d_name, &rest, 10);
9a7800af088cc013573310504ae76e325d44d4b4Zbigniew Jędrzejewski-Szmek if (rest[0] != '\0')
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering continue;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (i < 1)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering continue;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering if (read_one_line_file(str, &address) >= 0) {
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering /* match slot address with device by stripping the function */
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering hotplug_slot = i;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering free(address);
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
29abad107f8610e73b2fc091216040b579c75453Zbigniew Jędrzejewski-Szmek if (hotplug_slot > 0)
29abad107f8610e73b2fc091216040b579c75453Zbigniew Jędrzejewski-Szmek break;
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden }
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering closedir(dir);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (hotplug_slot > 0) {
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering s = names->pci_slot;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering l = sizeof(names->pci_slot);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (domain > 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "P%d", domain);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "s%d", hotplug_slot);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (func > 0 || is_pci_multifunction(names->pcidev))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "f%d", func);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (dev_id > 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = strpcpyf(&s, l, "d%d", dev_id);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (l == 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering names->pci_path[0] = '\0';
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringout:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering udev_device_unref(pci);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return err;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic int names_pci(struct udev_device *dev, struct netnames *names) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct udev_device *parent;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering parent = udev_device_get_parent(dev);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!parent)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -ENOENT;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* check if our direct parent is a PCI device with no other bus in-between */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering names->type = NET_PCI;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering names->pcidev = parent;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!names->pcidev)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -ENOENT;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering }
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering dev_pci_onboard(dev, names);
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering dev_pci_slot(dev, names);
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering return 0;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering}
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poetteringstatic int names_usb(struct udev_device *dev, struct netnames *names) {
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering struct udev_device *usbdev;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering char name[256];
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering char *ports;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering char *config;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering char *interf;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering size_t l;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering char *s;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering if (!usbdev)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -ENOENT;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* get USB port number chain, configuration, interface */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strscpy(name, sizeof(name), udev_device_get_sysname(usbdev));
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering s = strchr(name, '-');
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering if (!s)
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering return -EINVAL;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering ports = s+1;
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek s = strchr(ports, ':');
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek if (!s)
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek return -EINVAL;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering s[0] = '\0';
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering config = s+1;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering s = strchr(config, '.');
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (!s)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering return -EINVAL;
8e33886ec582336564ae11b80023abe93d7599c0Zbigniew Jędrzejewski-Szmek s[0] = '\0';
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering interf = s+1;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* prefix every port number in the chain with "u"*/
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering s = ports;
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering while ((s = strchr(s, '.')))
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering s[0] = 'u';
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering s = names->usb_ports;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering l = strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering /* append USB config number, suppress the common config == 1 */
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (!streq(config, "1"))
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering l = strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering /* append USB interface number, suppress the interface == 0 */
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (!streq(interf, "0"))
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering l = strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
87b0284327e34a4b96c22085fa2cdb3219294991Zbigniew Jędrzejewski-Szmek if (l == 0)
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek return -ENAMETOOLONG;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering names->type = NET_USB;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering return 0;
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering}
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poetteringstatic int names_bcma(struct udev_device *dev, struct netnames *names) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering struct udev_device *bcmadev;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering unsigned int core;
4941e4aca907f26bf74aa9efe1c70ccad1d10a82Zbigniew Jędrzejewski-Szmek
4941e4aca907f26bf74aa9efe1c70ccad1d10a82Zbigniew Jędrzejewski-Szmek bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
4941e4aca907f26bf74aa9efe1c70ccad1d10a82Zbigniew Jędrzejewski-Szmek if (!bcmadev)
4941e4aca907f26bf74aa9efe1c70ccad1d10a82Zbigniew Jędrzejewski-Szmek return -ENOENT;
4941e4aca907f26bf74aa9efe1c70ccad1d10a82Zbigniew Jędrzejewski-Szmek
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* bus num:core num */
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*d:%d", &core) != 1)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return -EINVAL;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering /* suppress the common core == 0 */
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering if (core > 0)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering snprintf(names->bcma_core, sizeof(names->bcma_core), "b%d", core);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering names->type = NET_BCMA;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return 0;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering}
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poetteringstatic int names_mac(struct udev_device *dev, struct netnames *names) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering const char *s;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering unsigned int i;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering unsigned int a1, a2, a3, a4, a5, a6;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek /* check for NET_ADDR_PERM, skip random MAC addresses */
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering s = udev_device_get_sysattr_value(dev, "addr_assign_type");
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (!s)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return EXIT_FAILURE;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering i = strtoul(s, NULL, 0);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (i != 0)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return 0;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering s = udev_device_get_sysattr_value(dev, "address");
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (!s)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return -ENOENT;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek return -EINVAL;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
4850d39ab72e7cb00a6e9c9aa4745c997674efa6Lennart Poettering /* skip empty MAC addresses */
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (a1 + a2 + a3 + a4 + a5 + a6 == 0)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return -EINVAL;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering names->mac[0] = a1;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering names->mac[1] = a2;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering names->mac[2] = a3;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering names->mac[3] = a4;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering names->mac[4] = a5;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering names->mac[5] = a6;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering names->mac_valid = true;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return 0;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering}
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering/* IEEE Organizationally Unique Identifier vendor string */
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poetteringstatic int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering char str[32];
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (!names->mac_valid)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return -ENOENT;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering /* skip commonly misused 00:00:00 (Xerox) prefix */
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering if (memcmp(names->mac, "\0\0\0", 3) == 0)
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek return -EINVAL;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X",
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek names->mac[0], names->mac[1], names->mac[2],
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek names->mac[3], names->mac[4], names->mac[5]);
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringstatic int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen const char *s;
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen const char *p;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering unsigned int i;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering const char *devtype;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering const char *prefix = "en";
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering struct netnames names = {};
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int err;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek /* handle only ARPHRD_ETHER devices */
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering s = udev_device_get_sysattr_value(dev, "type");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!s)
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek return EXIT_FAILURE;
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering i = strtoul(s, NULL, 0);
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering if (i != 1)
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering return 0;
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering /* skip stacked devices, like VLANs, ... */
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering s = udev_device_get_sysattr_value(dev, "ifindex");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!s)
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering return EXIT_FAILURE;
8b38f3cc3eb73adf9536cb73d0f319e60d42ea0cLennart Poettering p = udev_device_get_sysattr_value(dev, "iflink");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!p)
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering return EXIT_FAILURE;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!streq(s, p))
a6e87e90ede66815989ba2db92a07102a69906feLennart Poettering return 0;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering devtype = udev_device_get_devtype(dev);
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering if (devtype) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (streq("wlan", devtype))
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering prefix = "wl";
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering else if (streq("wwan", devtype))
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering prefix = "ww";
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering err = names_mac(dev, &names);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (err >= 0 && names.mac_valid) {
553acb7b6b8d4f16a4747b1f978e8b7888fbfb2cZbigniew Jędrzejewski-Szmek char str[IFNAMSIZ];
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix,
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering names.mac[0], names.mac[1], names.mac[2],
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek names.mac[3], names.mac[4], names.mac[5]);
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ieee_oui(dev, &names, test);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering /* get PCI based path names, we compose only PCI based paths */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering err = names_pci(dev, &names);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (err < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto out;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering /* plain PCI device */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.type == NET_PCI) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char str[IFNAMSIZ];
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.pci_onboard[0])
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard) < (int)sizeof(str))
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.pci_onboard_label)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard_label) < (int)sizeof(str))
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str);
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen if (names.pci_path[0])
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_path) < (int)sizeof(str))
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.pci_slot[0])
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_slot) < (int)sizeof(str))
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto out;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering /* USB device */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering err = names_usb(dev, &names);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (err >= 0 && names.type == NET_USB) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char str[IFNAMSIZ];
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.pci_path[0])
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str))
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.pci_slot[0])
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto out;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering /* Broadcom bus */
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering err = names_bcma(dev, &names);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (err >= 0 && names.type == NET_BCMA) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char str[IFNAMSIZ];
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.pci_path[0])
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.bcma_core) < (int)sizeof(str))
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (names.pci_slot[0])
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.bcma_core) < (int)sizeof(str))
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering goto out;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringout:
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return EXIT_SUCCESS;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringconst struct udev_builtin udev_builtin_net_id = {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering .name = "net_id",
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering .cmd = builtin_net_id,
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering .help = "network device properties",
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering};
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering