2011-05-27 78 views
1

所以我有創建Linux TAP接口的Python代碼,但它總是隨機出現一個自動生成的MAC地址。爲了簡化測試,我想在初始化後爲接口手動分配一個MAC地址。我知道我可以用SIOCSIFHWADDR ioctl和struct ifreq來做到這一點,但是我有幾個關於實現的問題。如何調用SIOCSIFHWADDR ioctl在Python中更改MAC地址?

這裏是C結構:

struct ifreq 
{ 
# define IFHWADDRLEN 6 
# define IFNAMSIZ  IF_NAMESIZE 
union 
    { 
    char ifrn_name[IFNAMSIZ];  /* Interface name, e.g. "en0". */ 
    } ifr_ifrn; 

union 
    { 
    struct sockaddr ifru_addr; 
    struct sockaddr ifru_dstaddr; 
    struct sockaddr ifru_broadaddr; 
    struct sockaddr ifru_netmask; 
    struct sockaddr ifru_hwaddr; 
    short int ifru_flags; 
    int ifru_ivalue; 
    int ifru_mtu; 
    struct ifmap ifru_map; 
    char ifru_slave[IFNAMSIZ];  /* Just fits the size */ 
    char ifru_newname[IFNAMSIZ]; 
    __caddr_t ifru_data; 
    } ifr_ifru; 
}; 

現在我認爲我只需要填寫hwaddr領域,但是這是一個聯盟,我不知道如何在Python中創建的結構。

調用SIOCSIFHWADDR ioctl和struct ifreq以在Python中更改接口的MAC地址的最佳方式是什麼?

謝謝!

+0

你想在Python或C? – 2011-05-27 16:12:29

+0

在Python中,我的主要問題是構建傳遞給ioctl的結構。 – 2011-05-27 16:15:43

回答

6

來自:http://nullege.com/codes/show/[email protected]@[email protected]@[email protected]

def set_mac(self, newmac): 
    ''' Set the device's mac address. Device must be down for this to 
     succeed. ''' 
    macbytes = [int(i, 16) for i in newmac.split(':')] 
    ifreq = struct.pack('16sH6B8x', self.name, AF_UNIX, *macbytes) 
    fcntl.ioctl(sockfd, SIOCSIFHWADDR, ifreq) 

我已經使用了很多從該模塊的聯網方式;很有用!

+1

我希望我以前知道那個模塊。謝謝! – 2011-05-31 12:54:02

0

A union只是表示有多種方式來思考內容。你只有在一個有興趣,這一個:

struct ifreq_set_hwaddr 
{ 
# define IFHWADDRLEN 6 
# define IFNAMSIZ  IF_NAMESIZE 
    char ifrn_name[IFNAMSIZ];  /* Interface name, e.g. "en0". */ 
    struct sockaddr ifru_hwaddr; 
}; 

請注意,我認爲struct sockaddr具有相同(或嚴格)對齊要求與其他工會會員。如果不是,你可能需要一些填充。

0

您將spawn/sbin/ip作爲子進程生成,例如

/sbin/ip link set dev dummy0 address 02:23:45:67:89:ab 

這會省很多麻煩。