Postagem em destaque

Obtendo o endereço MAC da interface de rede


Para quem não sabe o nome MAC que dizer (Media Access Control), um endereço físico associado a uma interface de comunicação que realiza a conexão de rede de um dispositivo, esse endereçamento é único, não havendo duas interfaces de rede com o mesmo endereço no sistema. Apesar do assunto ser interessante e de suma importância, não vou entrar em mais detalhes pois não é o objetivo.

Apesar do comando ifconfig ser considerado obsoleto, vou utilizá-lo para essa tarefa, pois a maioria dos usuários estão mais familiarizados com a sua utilização. O ifconfig exibe detalhes sobre uma determinada interface de rede ou quando a interface é omitida todas são listadas.


juliano@shellscriptx:~$ ifconfig
enp3s0    Link encap:Ethernet  HWaddr 44:1e:a1:77:7c:10  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:1833 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1833 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:168110 (168.1 KB)  TX bytes:168110 (168.1 KB)

wlo1      Link encap:Ethernet  HWaddr 70:f1:a1:ed:8c:cf  
          inet addr:192.168.1.104  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::69ef:d7f2:6d86:70c8/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9926 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9413 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4731060 (4.7 MB)  TX bytes:1353632 (1.3 MB)

O endereço mac contém um conjunto separado por dois algarismo hexadecimais que seguem seguinte padrão: xx:xx:xx:xx:xx:xx e é exatamente o que desejo filtrar e separar das demais informações.

Sabemos que o mac está localizado na mesma linha que contém a expressão HWaddr e evidentemente poderia utilizar awk '/HWaddr/'... para extrair a tal coluna e sem contar que seria mais simples, levando em consideração um ambiente controlado. Porque estou falando isso ? Pois pode ocorrer variações no retorno do comando de sistema para sistema, onde a expressão HWaddr pode não estar presente ou até mesmo uma única letra minúscula poderia comprometer a filtragem.

Qual a melhor saída ?

Criar uma expressão regular para validação do formato de endereçamento, garantindo assim a filtragem do campo independentemente da sua localização no texto. Tenha sempre em mente, se procura um padrão, evite referencias concorrentes e vá direto ao padrão.

Veja como obtenho o mac da minha interface de rede enp3s0.

juliano@shellscriptx:~$ ifconfig enp3s0 | grep -Ewo '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}'
44:1e:a1:77:7c:10

Entendendo a regex:


Para complementar, utilizo o parâmetro -o que informa ao grep que seja exibido somente o padrão casado, suprimindo o restante das informações, -w que força casar o padrão completo e não menos importante o -E que ativa a expressão regular estendida.

Finalizando, vou criar uma função que facilita a aplicação do comando e que recebe como parâmetro o nome da interface.

# Sintaxe: get_mac <interface>
get_mac()
{
    # Lista as informações da interface armazenada em $1 e 
    # aplica a regex extraindo somente o campo mac address.
    # Caso o nome da interface seja omitido, imprime a
    # mensagem de erro e sai função.
    ifconfig ${1:?$FUNCNAME: requer nome da interface.} | \
     grep -Ewo --color=never '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' # -> xx:xx:xx:xx:xx:xx

    # status
    return 0
}

Testando...

juliano@shellscriptx:~$ get_mac enp3s0
44:1e:a1:77:7c:10
juliano@shellscriptx:~$ get_mac wlo1
70:f1:a1:ed:8c:cf
juliano@shellscriptx:~$ get_mac
bash: 1: get_mac: requer nome da interface.

Pronto, agora temos nossa função que retorna o endereço MAC da interface de rede especificada. 

Então é isso ai jovens, espero que tenha ajudado de alguma forma, valeu e até mais.

Comentários

  1. Legal cara, muito massa o blog.
    Parabéns!

    # Para listar todas as interfaces de uma vez utilizando a regex criada no post, pode-se fazer da seguinte forma:

    for interface in $(ifconfig | grep ^[a-z] | grep -v lo | cut -d':' -f1)
    do

    echo -ne "$interface\t: "
    ifconfig $interface | grep -Ewo '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}'

    done

    ;-)

    ResponderExcluir
    Respostas
    1. Uma alternativa para listar as interfaces de rede é utilizando a seguinte linha de comando:

      ifconfig | egrep -o '^\w+'

      Até mesmo o 'lo' será listado, ai é só aplicar mais um grep -v e pronto. :D

      Excluir
  2. Muito massa , se puder colocar para pegar a interface de rede já na função creio que seria um bom complemento pois o nome muda caso queira usar o script em vários micros já facilita Show

    ResponderExcluir
    Respostas
    1. Sim, em breve vou criar função um pouco mais complexas e que aceitam parâmetros para obter determinadas informações.

      Excluir
  3. /sbin/ifconfig |grep HWaddr | cut -d " " -f 5

    Ou ainda

    /sbin/ifconfig | grep HWaddr | cut -d ":" -f 1-6

    ResponderExcluir
    Respostas
    1. Boa !! Como havia comentado em um ambiente controlado podemos criar várias alternativas, porém só devemos ficar atentos nas variamos do retorno. Porque se a palavra HWaddr estiver ausente, o código pode apresentar problemas. :(

      Excluir
  4. Para aqueles que curtem usar o comando ip:

    get_mac()
    {
    ip address show ${1:?$FUNCNAME: requer nome da interface.} | \
    grep -Ewo --color=never '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' | \
    head -n1

    return 0
    }

    ResponderExcluir

Postar um comentário

Contato

Nome

E-mail *

Mensagem *