Resposta curta
De todas as minhas pesquisas e tentativas, eu diria que não é possível fazer um programa que gere uma ID única respeitando as seguintes restrições.
- O ID deve ser o mesmo sempre que gerado no mesmo computador.
- O ID deve ser diferente se gerado em computadores diferentes.
- O programa deve ser executado como usuário.
- O programa deve ser compatível com qualquer distribuição do Linux com uma versão do kernel 2.6 ou superior
- O ID pode ser diferente se o computador for modificado (por exemplo: substituição de hardware)
- O programa não deve depender de ferramentas de terceiros que precisam ser instaladas no computador
Resposta longa
Aqui vou apresentar minha tentativa com os endereços mac.
O objetivo aqui era encontrar uma maneira de recuperar os endereços de todas as interfaces de rede físicas. Como um usuário normal, eu vi que a maneira mais fácil de encontrar endereços mac seria ler os arquivos do sistema no diretório "/ sys". Esses arquivos estão disponíveis desde o linux 2.6, o que é perfeito.
Minha pesquisa me levou a esses conjuntos de regras: link
O uso da biblioteca do udev, conforme recomendado nessas regras, não é possível porque tem que ser adicionado externamente. Então eu mergulhei na fonte que pode ser encontrada aqui: link
O que eu aprendi com isso, é que para recuperar os endereços mac você deve procurar por "sys / subsystem", se estiver presente, procure por um diretório "net" dentro dele, e você encontrará diretórios em cada interface de rede. Se não houver pasta "subsistema", você deve procurar nas pastas "sys / class", "sys / bus" e "sys / block" pelo diretório "net". Na verdade, eu sempre os encontrei em "classe", mas as regras diziam que não deveria ser esperado.
Acima eu disse que na pasta "net", você encontrará os diretórios de rede, isso não é inteiramente verdade. No linux 2.6 (eu usei o RHEL 4), são diretórios e dentro você encontrará, entre outros, o arquivo "address" contendo o endereço mac um symlink que direciona um diretório em "sys / devices". Se em uma versão linux superior, será diretamente um symlink para um diretório em "/ sys / devices", no qual você encontrará o arquivo "address". (Eu tentei no RHEL 6, Debian 7, Debian 8, Ubuntu 15 e Ubuntu 15 com o kernel atualizado para o linux 4.3)
Eu nunca vi o diretório "/ sys / subsystem" mesmo na nova versão do linux (4.3).
Novo layout do sysfs (> = linux 3): Para informar a interface física do virtual, eu queria olhar para o caminho do dispositivo. O link simbólico que tenho em "/ sys / class / net" é direcionado para esses diretórios:
- "/ sys / devices / pci0000: 00/0000: 00: 11.0 / 0000: 02: 01.0 / net / eth0"
- "/ sys / devices / virtual / net / eth1"
A eth1 era um nic virtual fictício que eu criei seguindo este tópico: Como posso criar uma interface ethernet virtual em uma máquina sem um adaptador físico?
Então você pode ver que o virtual está em uma pasta "virtual", de modo que seria o caminho para diferenciá-los.
Layout antigo do sysfs (linux 2.6):
A interface de rede virtual não tem um link simbólico "dispositivo" em seus diretórios.
Você encontrará "/ sys / class / net / eth0 / device - > / sys / devices ...." Mas se houvesse um eth1 virtual, não haveria tal link simbólico em "/ sys / class / net / eth1".
Então, no geral, usando "opendir", "readdir", "access ('...', F_OK)", "fopen" .. você pode recuperar os endereços mac de apenas interfaces físicas.
Depois, apenas ordene-os, para ter certeza de que eles virão na mesma ordem, depois anexe tudo em um buffer e use um SHA1 do openssl, faça uma pequena análise para fazer com que pareça um UUID e você é bom vai.
Mas o problema é que eu não queria confiar no fato de que haveria uma pasta "virtual" em qualquer lugar no devpath para um dispositivo de rede. Nunca é dito nas regras, acima, que esse sempre seria o caso. Então o problema não pode ser responder dessa maneira.
Espero que todas as minhas pesquisas ajudem alguém.