Я пытаюсь заставить работать Ethernet через USB для своего Nexus S. Я использую Ice Cream Sandwich v4.0.3 и пересобрал ядро с включенной поддержкой USB-гаджетов. Когда я подключаю телефон к своей машине с Linux и запускаю ifconfig -a, usb0 появляется как на телефоне, так и на машине с Linux. Я запускаю ifconfig для настройки обеих сторон, и все выглядит правильно, но я не могу выполнить ping ни с одной из сторон:
PING 192.168.22.2 (192.168.22.2) 56(84) bytes of data.
From 192.168.22.1 icmp_seq=1 Destination Host Unreachable
From 192.168.22.1 icmp_seq=2 Destination Host Unreachable
У меня также есть N900 с Maemo Linux, который поддерживает Ethernet через USB. Я сравнил вывод ethtool, ifconfig, route и arp между N900 и Nexus S, и все они очень похожи, за исключением вывода arp. Он показывает (неполный) для HWAddress для подключения Android:
Address HWtype HWaddress Flags Mask Iface
10.1.3.1 ether 00:1B:17:05:30:13 C eth0
192.168.22.2 (incomplete) usb0
Единственная другая подсказка, которую я имею, это то, что ifconfig показывает на стороне Linux:
usb0 Link encap:Ethernet HWaddr 66:E4:64:10:D1:A9
inet addr:192.168.22.1 Bcast:192.168.22.255 Mask:255.255.255.0
inet6 addr: fe80::64e4:64ff:fe10:d1a9/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 b) TX bytes:9039 (8.8 KiB)
и на стороне Android:
usb0 Link encap:Ethernet HWaddr 7A:78:28:52:9C:A0
inet addr:192.168.22.2 Bcast:192.168.22.255 Mask:255.255.255.0
inet6 addr: fe80::7878:28ff:fe52:9ca0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:202 errors:0 dropped:202 overruns:0 frame:0
TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:47294 (46.1 KiB) TX bytes:1728 (1.6 KiB)
Обратите внимание на отброшенные пакеты на стороне Android.
Кажется, я почти у цели... какие-нибудь предложения?
РЕДАКТИРОВАТЬ:
Я пересобрал ядро с помощью модуля ядра гаджета (я пробовал и g_cdc, и g_ether) вместо встроенной поддержки. Я не уверен, связано ли следующее с этим или просто не синхронизировано в моем предыдущем посте. Если я запускаю ping с любой стороны, номера TX и RX фактически совпадают с обеих сторон, но сторона Android по какой-то причине их отбрасывает.
Хост-сторона ifconfig:
usb0 Link encap:Ethernet HWaddr 12:23:34:45:56:67
inet addr:192.168.22.1 Bcast:192.168.22.255 Mask:255.255.255.0
inet6 addr: fe80::1023:34ff:fe45:5667/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:33 errors:0 dropped:0 overruns:0 frame:0
TX packets:734 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1140 (1.1 KiB) TX bytes:37684 (36.8 KiB)
Сторона Android ifconfig:
usb0 Link encap:Ethernet HWaddr 5E:89:C6:D8:BC:08
inet addr:192.168.22.2 Bcast:192.168.22.255 Mask:255.255.255.0
inet6 addr: fe80::5c89:c6ff:fed8:bc08/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:734 errors:0 dropped:734 overruns:0 frame:0
TX packets:33 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:27408 (26.7 KiB) TX bytes:1602 (1.5 KiB)
ЕЩЕ ОДНА РЕДАКЦИЯ!!
После использования arp на стороне хоста и ip на стороне Android для ручного добавления записей ошибки Destination Host Unreachable исчезли, но по-прежнему нет ответа на ping. Я запустил Wireshark на хосте, и сообщения с устройства неверны. Отображаемые MAC-адреса выглядят неправильно, а протокол неизвестен, поэтому просто отображается как 0x7aab. После просмотра фактических данных в сообщении оказывается, что к сообщению добавлены два нулевых байта. Если бы их убрать, вроде бы все заработало. Кто-нибудь когда-либо видел это или знает, где в коде это можно исправить?
ЕЩЕ ОДНА РЕДАКЦИЯ!!!
После загрузки всего этим утром я не стал создавать фальшивые записи ARP и снова запустил ping. Согласно Wireshark, от хоста пришло сообщение ARP, а от Droid пришло неизвестное сообщение, но они были одинаковой длины. Изучив содержимое сообщений, Droid также отправил то, что выглядело как действительное сообщение ARP, но оно было сдвинуто на 2 байта — два дополнительных байта в начале и два последних обрезанных.
Похоже, есть проблема с выравниванием байтов. Я нашел этот пост:
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg20797.html
и исходя из этого внес следующие изменения в drivers/usb/gadget/u_ether.c:
257,258c257
<
< //skb_reserve(skb, NET_IP_ALIGN);
---
> skb_reserve(skb, NET_IP_ALIGN);
513d511
< int i=0;
599,606d596
<
< if ((int)skb->data & 0x2) {
< skb_push(skb, 2);
< for (i=0; i<length; i++) {
< skb->data[i] = skb->data[i+2];
< }
< }
<
Теперь я могу пинговать в обоих направлениях через USB. Если кто-нибудь знает лучший способ решить эту проблему, пожалуйста, дайте мне знать, иначе я пойду с этим.
Дэвидбб
боббарк