You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.1 KiB
50 lines
1.1 KiB
#include <net/if.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/socket.h>
|
|
|
|
unsigned char get_byte(FILE *fp) {
|
|
unsigned char ret = 0;
|
|
for (int i = 0; i < 2; ++i) {
|
|
int c = getc(fp);
|
|
if (c == EOF)
|
|
perror("getc"), exit(1);
|
|
c = c > '9' ? c - 'a' + 0xa : c - '0' + 0x0;
|
|
if (c > 0xf)
|
|
fputs("unexpected char in serial number\n", stderr), exit(1);
|
|
ret <<= 4;
|
|
ret |= c;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if (argc != 2)
|
|
fputs("Expected a single argument.\n", stderr), exit(1);
|
|
|
|
struct ifreq dev;
|
|
strcpy(dev.ifr_name, argv[1]);
|
|
|
|
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (sock < 0)
|
|
perror("socket"), exit(1);
|
|
|
|
if (ioctl(sock, SIOCGIFHWADDR, &dev) < 0)
|
|
perror("get hwaddr ioctl"), exit(1);
|
|
|
|
FILE *fp = fopen("/sys/firmware/devicetree/base/serial-number", "r");
|
|
if (!fp)
|
|
perror("serial-number fopen"), exit(1);
|
|
|
|
dev.ifr_hwaddr.sa_data[0] = get_byte(fp);
|
|
if (fseek(fp, 4, SEEK_CUR))
|
|
perror("fseek"), exit(1);
|
|
for (uint i = 1; i < 6; ++i)
|
|
dev.ifr_hwaddr.sa_data[i] = get_byte(fp);
|
|
|
|
if (ioctl(sock, SIOCSIFHWADDR, &dev) < 0)
|
|
perror("set hwaddr ioctl"), exit(1);
|
|
}
|