You are here

How to assign a fixed IP address to an Ethernet over USB network interface

Tux27-Jan-2016 - update: see at the end of the article.

I'm currently developing a system where an Android smartphone, used as a (sophisticated Smile) sensor, is connected to an embedded PC via a USB cable. The PC runs Linux (Mint 14). I use USB tethering to transfer information from the smartphone to the PC and from the PC to the smartphone. The problem is that every time USB tethering is activated, a new IP address (in the subnetwork 192.168.42.0/24) is assigned to the usb0 network interface created on the PC. This means that the application code running on the smartphone can't easily initiate a communication with the PC.

I tried first to prevent Network Manager from running. But this was not the right solution, as I need to use some other network interfaces (a fixed one, and a 4G network one), and I didn't want to deeply modify the PC system configuration. Then, looking at Network Manager configuration file, I discovered that it was possible to request it not to manage some network interfaces. But here, a second problem appeared: Network Manager needs a MAC address, for this option. And the rndis_host driver handling USB tethering uses a new MAC address for every activation...

So, I had to find a way to tell this driver to use a fixed MAC address. I didn't find how to implement that exact solution, but, thanks to this article, I was able to set up a working configuration. The idea is to use udev so that as soon as the device is activated, associated network interface is brought down, and configured with the right MAC address, before being brought up again.

Here are the details:

  • connect the smartphone to the PC with the USB cable
  • on the smartphone, activate USB tethering, using the Settings application
  • on the PC, enter the dmesg command. A message similar to this one should be displayed:
rndis_host 2-1.2:1.0: >usb0: register 'rndis_host' at usb-0000:00:1d.0-1.2, RNDIS device, 96:53:6d:9b:5e:a5
  • still on the PC, enter the following command (adapt usb0 if required) 
udevadm info -a -p /sys/class/net/usb0
  • you will get udev information for usb0 device, and then for its parents. Look for the device with ATTRS{serial} information. 
  • create the file /etc/udev/rules.d/90-local.rules with the following content (on the same line, xxxx being the value displayed for ATTRS{serial}), setting ownership to root:root:
ACTION=="add", DRIVERS=="usb", ATTRS{serial}=="xxxx", RUN+="/etc/udev/scripts/android"
  • create the file /etc/udev/scripts/android with the following content (you can choose any MAC address, provided that it is a locally administered address, i.e. the second least significant bit of the most significant byte is set to 1):
#!/bin/bash
ifconfig usb0 down
ifconfig usb0 hw ether 02:11:22:33:44:55
ifconfig usb0 192.168.42.1
ifconfig usb0 up
  • make this file executable, and set its ownership to root:root
  • reload udev rules:
sudo udevadm control --reload-rules
  • prevent Network Manager from managing usb0, adding into /etc/NetworkManager/NetworkManager.conf file the MAC address you specified in the script:
[keyfile]
unmanaged-devices=mac:02:11:22:33:44:55
  • restart Network Manager:
sudo service network-manager restart

That's it! 

If the smartphone is replaced by another one, modify the serial attribute in the udev rule.

27-Jan-2016 - update

A few days ago, Marcello Messori kindly informed me about a new keyword, for the keyfile section: interface-name. This means that it's possible to specify the network interface without having to go through the MAC address steps. The keyfile section would be:

unmanaged-devices=interface-name:usb0

But for me, there is a problem. I use Linux Mint 17 MATE, and provided version of NetworkManager is 0.9.8.8. The interface-name keyword has been added in version 0.9.10. So, it's not available to me Frown. But if you run a more recent version of NetworkManager than mine, you should be able to bypass the MAC address stuff...