1 puan yazan GN⁺ 2025-06-09 | 1 yorum | WhatsApp'ta paylaş
  • Android'de USB Ethernet desteği ve ayarlar menüsü bulunsa da, CDC Ethernet aygıtları çekirdek tarafından algılansa bile ağ ayarlarına kadar bağlanmayabilir
  • Temel neden, EthernetTracker'ın yalnızca config_ethernet_iface_regex ile eşleşen arayüzleri izlemesi ve varsayılan eth\d değerinin usb0 gibi CDC arayüzlerini dışarıda bırakmasıdır
  • Linux CDC Ethernet sürücüleri EEM, ECM ve NCM aygıtlarını sırasıyla cdc_eem, cdc_ether, cdc_ncm olarak yakalayıp /sys/class/net altında usb0 oluşturur, ancak Android ayarları devre dışı kalmaya devam eder
  • Normal kullanıcı ayarlarıyla bunu aşmak mümkün değildir; root erişiminden sonra config_ethernet_iface_regex değerini değiştirmek gerekir
  • Android için USB Ethernet adaptörü seçerken, CDC standart aygıtları yerine ethX adı oluşturan üretici/yonga setine özel sürücü tabanlı aygıtları aramak gerekir

Sonuç: engel çekirdek sürücüsü değil, arayüz adı filtresi

  • Android'in EthernetTracker servisi yalnızca adı ethX olan arayüzleri Ethernet arayüzü olarak kabul eder
  • Linux'un CDC Ethernet sürücüleri arayüz adını usbX olarak oluşturur
  • Bu ad farkı nedeniyle CDC Ethernet aygıtları Android çekirdeğinde algılansa bile Ethernet ayarları ve ağ yönetim katmanında yok sayılır
  • Bu sorun normal ayarlarla çözülemez; yalnızca root sonrası config_ethernet_iface_regex değerini değiştirme yöntemi mümkündür

Android USB Ethernet desteğini cihaz bazında doğrulamak zor

  • Android'de USB Ethernet adaptörü desteği ve ilgili menüler bulunur
  • Belirli bir Android cihazında hangi USB Ethernet yonga setinin çalıştığını doğrulamak zordur, çünkü üreticiler destek listelerini neredeyse hiç yayımlamaz
  • Gerçek kullanıcılar genelde şu bilgilere dayanmak zorunda kalır
    • Telefon üreticisinin resmi aksesuar olarak sattığı USB Ethernet adaptörü
    • Aynı cihazı kullanan birinin belirli bir adaptörü başarıyla kullandığını söyleyen forum gönderileri
  • Çekirdek yapılandırmasına bakarak, telefon çekirdeğinin hangi USB Ethernet sürücülerini içerdiği bir ölçüde anlaşılabilir

Telefon çekirdeği yapılandırması nasıl bulunur

  • Android, Linux çekirdeği üzerinde çalışır ve çekirdek yapılandırması desteklenen özellikleri ile donanım sürücülerini belirler
  • Android 11 sonrasında çıkan cihazlar Android Common Kernel ve GKI kernel tabanlıdır
    • Google çekirdeği derler, üreticiler ise cihaza özgü unsurları çekirdek modüllerine ekler
    • Yapılandırma Android çekirdek deposundaki arch/$ARCH/configs/gki_defconfig içinde görülebilir
    • 64 bit ARM cihazlarda örneğin arch/arm64/configs/gki_defconfig dosyasına bakılır
  • Çekirdek sürümü ve mimari ADB üzerinden uname -a ile doğrulanabilir
    • Örnek çıktıda 4.19.113-26203352 çekirdek sürümü ve aarch64 mimarisi yer alır
  • Android 10 ile çıkan Samsung Galaxy S20 örneğinde, Android 13'e yükseltildikten sonra bile çekirdek Linux 4.19 tabanlı kalmıştır
    • Samsung cihaz kaynakları opensource.samsung.com adresinde bulunabilir
    • Samsung kaynaklarındaki build_kernel.sh içinde vendor/x1q_usa_singlex_defconfig gibi çekirdek yapılandırma dosyası adları bulunabilir
  • Şanslıysanız gerçek derleme yapılandırması /proc/config.gz içinde sıkıştırılmış dosya olarak bulunur
    • adb shell zcat /proc/config.gz > my_kernel_config ile kaydedilebilir
    • Yoksa zcat: /proc/config.gz: No such file or directory çıktısı alınır ve üreticinin çekirdek kaynaklarına bakmak gerekir

USB Ethernet sürücüsü desteği nasıl doğrulanır

  • USB Ethernet ile ilgili çekirdek yapılandırmaları genelde USB_NET ile başlar
  • Çekirdek yapılandırma dosyasında şu şekilde kontrol edilebilir
grep USB_NET my_kernel_config
  • Örnek yapılandırmada çeşitli USB ağ sürücüleri bulunur
    • CONFIG_USB_NET_DRIVERS=y
    • CONFIG_USB_NET_AX8817X=y
    • CONFIG_USB_NET_AX88179_178A=y
    • CONFIG_USB_NET_CDCETHER=y
    • CONFIG_USB_NET_CDC_EEM=y
    • CONFIG_USB_NET_CDC_NCM=y
  • Yapılandırma değerleri sürücünün nasıl dahil edildiğini gösterir
    • y: sürücü çekirdeğe gömülüdür ve ilgili yonga setini kesin olarak destekler
    • m: sürücü modül olarak derlenmiştir; üretici bunu eksik bırakmadıysa yüklenebilir
    • is not set: sürücü ne gömülüdür ne de modüldür, dolayısıyla kullanılamama ihtimali yüksektir
  • Yapılandırma seçenekleri ile yonga seti eşlemesi çekirdek ağacındaki drivers/net/usb/Kconfig dosyasında görülebilir
  • Belirli bir USB Ethernet adaptörünün hangi yonga setini kullandığını anlamak hâlâ zordur, çünkü üreticiler bunu çoğu zaman açıkça belirtmez

CDC Ethernet ne yapar

  • CDC, Communications Device Class ifadesinin kısaltmasıdır ve USB aygıtı üreticilerinin uyabileceği bir standartlar kümesidir
  • CDC Ethernet ile ilgili üç standart vardır
    • EEM: Ethernet Emulation Model; uygulaması en basit olanıdır ve düşük performanslı aygıtlarda desteklenmesi kolaydır
    • ECM: Ethernet Control Model; hem ana makine hem de aygıt tarafındaki uygulama daha karmaşıktır, ancak EEM'den daha iyi performans vadeder
    • NCM: Network Control Model; ECM'in ardılıdır ve daha yüksek hız vadeder
  • CDC standardının amacı, işletim sistemlerinin farklı aygıtlar için ortak sürücüler sunabilmesidir
  • Linux, CDC Ethernet'in hem ana makine hem de aygıt tarafını uygular
    • USB OTG portuna sahip Raspberry Pi gibi aygıtlarda çekirdek bu portu bir Ethernet adaptörü gibi gösterebilir
    • Böylece gömülü yönlendirici, güvenlik duvarı, VPN ağ geçidi gibi aygıtlar ana makine tarafında normal bir Ethernet adaptörü gibi görünebilir
  • Linux, Windows ve macOS CDC Ethernet aygıt sürücülerini içerir, ancak iOS içermez

Android çekirdeği CDC aygıtlarını algılar

  • Samsung Galaxy S20 çekirdek yapılandırmasında üç CDC Ethernet standardının desteği de vardır
    • CONFIG_USB_NET_CDCETHER=y
    • CONFIG_USB_NET_CDC_EEM=y
    • CONFIG_USB_NET_CDC_NCM=y
  • Google GKI çekirdeğinde ECM ve NCM eksik görünüyor; EEM ise modül olarak dahil edilmiş görünüyor
  • OTG portu Ethernet gadget olarak ayarlanmış aygıtlar Mac, Ubuntu ve Windows'ta çalıştı, ancak Galaxy S20'de Android Ethernet ayarları devre dışı kaldı
  • Android'de /sys/class/net kontrol edildiğinde CDC aygıtı bağlandığında usb0 görünür
adb shell ls /sys/class/net
  • ifconfig usb0 çıktısında sürücünün CDC ailesinden biri tarafından yakalandığı doğrulanır
    • EEM modu: Driver cdc_eem
    • ECM modu: Driver cdc_ether
    • NCM modu: Driver cdc_ncm
  • Üç durumda da arayüz algılanır, ancak down durumundadır ve Android Ethernet ayarları etkinleşmez

EthernetTracker'ın düzenli ifadesi usb0'ı eler

  • Çekirdek düzeyinde CDC Ethernet aygıtları normal biçimde algılandığı için sorun çekirdeğin üzerindeki Android ağ yönetim katmanındadır
  • Android kaynak kodunda Ethernet ile ilgili Java kodu izlendiğinde ilgili servis olarak EthernetTracker.java ortaya çıkar
  • EthernetTracker, çekirdekten gelen yeni ağ arayüzü bildirimlerini Netlink soketi üzerinden alır ve bunun geçerli bir Ethernet arayüzü olup olmadığını değerlendirir
  • Geçerlilik kontrolü, arayüz adının mIfaceMatch düzenli ifadesiyle eşleşip eşleşmediğine bakılarak yapılır
private boolean isValidEthernetInterface(String iface) {
    return iface.matches(mIfaceMatch) || isValidTestInterface(iface);
}
  • mIfaceMatch, config_ethernet_iface_regex kaynağından alınır
  • Android kaynak kodundaki varsayılan değer şöyledir
<string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>
  • eth\d, eth sonrasında bir rakam gelen adları geçiren bir düzenli ifadedir
  • CDC Ethernet aygıtları usb0 gibi usb ile başladığından EthernetTracker bunları izlemez
  • Bu ayar kullanıcı ayarlarından değiştirilemez; yalnızca root ile düzenlenebilir

Standart aygıtlardan kaçınma paradoksu

  • CDC Ethernet, USB ağ aygıtları için bir standarttır; ancak Android'de arayüz adı düzenli ifadesi nedeniyle gerçek kullanım yolu kapanır
  • Modern GKI çekirdeği EEM adaptör desteğini içeriyor gibi görünse de, usb0 adı düzenli ifadeye uymadığı için Android'in ağ ayarlarına taşınmaz
  • Android'de USB Ethernet adaptörü seçerken CDC standart aygıtları değil, üretici/yonga setine özel sürücülerle ethX arayüzü oluşturan aygıtları aramak gerekir
  • Olası düzeltme yönlerinden biri config_ethernet_iface_regex değerini (eth|usb)\d gibi bir kalıba çevirmektir

1 yorum

 
GN⁺ 2025-06-09
Hacker News yorumları
  • Bu yazıyı, eski iş yerimde Android cihazlarla CDC Ethernet adaptörlerini çalıştırmaya uğraşarak geçirdiğim haftalardan sonra yazmıştım.
    Daha sonra birkaç kişi, MAC adresindeki belirli bir biti ters çevirince çekirdeğin usbX yerine ethX adını verdiğini söyledi; ama bunu kendim denemedim ya da yazıyı güncellemedim. Çünkü zaten başka bir işe geçmiştim ve Android cihazlar artık gündelik hayatımın büyük bir parçası değildi.
    Elbette bu yöntem yalnızca CDC cihazının MAC adresini doğrudan kontrol edebildiğinizde işe yarar. Örneğin başka bir Linux cihazının CDC adaptörü gibi davrandığı durumlarda.
  • İlginç bir derin analiz yazısı.
    Kaynağa baktığımda, Ekim 2023'te regex'in eth\\d yerine doğrudan * olarak değiştirildiğini gördüm; muhtemelen bu sorun çözülmüş gibi: https://android-review.googlesource.com/c/platform/packages/...
    Açıklamada “varsayılan değer Android U+’da hem usb\d+ hem de eth%d adlı arayüzleri içerir” deniyor; buradaki U+ sürüm 14 gibi görünüyor: https://en.wikipedia.org/wiki/Android_version_history
  • LineageOS commit geçmişine bakınca bu sorunun düzeltilip[0], uyumluluk sorunları nedeniyle geri alındığı[1], sonra geri almanın geri çevrildiği[2] ama görünüşe göre yalnızca en yeni Android sürümüne uygulandığı anlaşılıyor.
    Commit'leri doğru okuduysam Google tarafından biri de işin içindeydi; yani artık resmi Google build'lerine de girmiş olabilir.
    [0] https://github.com/LineageOS/android_packages_modules_Connec...
    [1] https://github.com/LineageOS/android_packages_modules_Connec...
    [2] https://github.com/LineageOS/android_packages_modules_Connec...
    • Lineage tarafında bunu bir süre önce bulup https://review.lineageos.org/c/LineageOS/android_packages_mo... değişikliğini oluşturdum.
      Ama kimse test etmedi ve benim de doğrudan doğrulama imkânım olmadığı için şu an beklemede. Her zaman birinin bildirdiği, birinin tesadüfen eline aldığı şeyler birbirine karışıyor; ama sonunda gerçek kullanıcı testine ihtiyaç var.
  • Android'in EthernetTracker servisinin yalnızca ethX adlı arayüzleri tanıdığı doğruysa, şu ana kadar duyduğum en aptalca tasarım bu.
    Linux dağıtımları bu sorunu 2000'lerde zaten çözmüştü. O zaman bile bazı aygıt sürücülerinin aygıt adı öneklerini kafasına göre verdiği açıktı; bu yüzden sistemi inceleyip bunun ne tür bir aygıt olduğunu bulmak gerekiyordu.
    Tutarlılık faydalı olduğu için arayüz adlarını değiştiren birden fazla araç da var; günümüzde çoğu Linux dağıtımı bunu udev ile otomatikleştiriyor. İçeride yaptığı şey, çekirdeğin SIOCSIFNAME ioctl çağrısını yapmak. Modern çekirdeklerde, adı "wlan*"—aslında "wlan%d"—olarak değiştirince "wifi" sonrasına otomatik olarak yeni bir numara atama özelliği de var.
    • Android'de NetworkManager kullanmak ve Android kablosuz ayarlar arayüzünün NetworkManager GUI'si gibi davranmasını sağlamak mantıklı olur mu merak ediyorum.
    • Bazı usbX cihazlarını başka modüllerin kullanması gerekiyor; ama o listeyi yönetmek istemediler. Bu yüzden doğrudan ethX yoluna gitmişler.
  • Android akıllı telefona USB seri cihaz bağlamaya çalışınca da benzer şekilde aptalca bir durum yaşanıyor.
    Bağlayınca çalışıyor gibi görünüyor, ama o USB seri arayüzünü kullanan bir uygulama yapmaya çalışırsanız olmuyor. Biraz kurcalayınca /dev/ttyACM0 gibi seri cihaza erişim izniniz olmadığını görüyorsunuz.
    Seri desteği çekirdekte var, ama root olmadan kullanıcı programlarından erişilemiyor.
    Daha da derine inince Android'de libusb benzeri, hatta belki onun üzerine kurulmuş kullanıcı alanı USB erişim özelliği olduğunu görüyorsunuz. Bu yüzden Android programından “ham” USB cihazları açabiliyorsunuz, ama seri USB cihazlarını açamıyorsunuz.

USB seri yalnızca USB üzerinde çalışan bir protokol ve pratikte FTDI gibi yarı tescilli protokol kümelerine daha yakın. Android için bu tür protokolleri kullanıcı alanında uygulayan yarım yamalak kütüphaneler var; sonuçta bazı USB seri aygıtlara erişilebiliyor
Android Chrome tarayıcısında WebUSB ile ham USB aygıtlarını açmak mümkün olacak gibi, ama WebSerial muhtemelen aynı nedenle çalışmayacaktır
Sonuçta şaşırtıcı olan şu: Madem öyle, çekirdekte USB seri desteği neden açık tutuluyor? Hata ayıklama için olabilir diye düşünüyorum

  • Telefonu root edip config_ethernet_iface_regex değerini değiştirmedikçe bu sorunu aşmanın yolu yok
    Sahip olduğum cihazda root yetkisinin önemli olmasının bir başka nedeni de bu
    • Ancak “root etme”, Android’in birçok güvenlik özelliğini ortadan kaldırır. Uygulamanın yalnızca gereken izinlere sahip olması yerine root ile tüm yetkilere sahip olabilmesi, devasa bir güvenlik açığı yaratır
      https://www.reddit.com/r/GrapheneOS/comments/13264di/is_root...
    • Ağ trafiğini istediği gibi atlatıp yönlendirebilmek, kullanıcı alanında süper kullanıcı yetkisi bulundurmamak için en büyük neden olabilir
      OEM’lerin bootloader kilidinin açılmasına izin vermesi için baskı yapılmasını destekliyorum, ama en azından Android’de saldırı yüzeyini muazzam ölçüde genişletmeyi haklı çıkaracak bir root kullanım senaryosu düşünmek zor
  • Android sinir bozucu biçimde aynı anda birden fazla ağa bağlanamıyor
    Örneğin internet erişimi olmayan ve varsayılan rota da duyurmayan bir Wi‑Fi ile hücresel ağı aynı anda kullanma durumu. Linux’ta da oluyor, Windows’ta da oluyor; Android ise inatla reddediyor
    Birçok varyant, interneti olmayan Wi‑Fi’ye bağlı kalmayı bile reddediyor ya da kullanıcıyı kafa karıştırıcı bir sürece sürüklüyor. Kendi uygulamanızı yazarsanız bunu yalnızca uygulama içinde mümkün kılan API’ler var, ama normal bir kullanıcının bunu sistem genelinde davranış haline getirmesinin yolu yok
    • iOS da aynı. Araç kamerasına bağlanıp videoları indirirken bir süre sonra “İnternet algılanmadı, hücresize geçilsin mi?” gibi bir açılır pencere çıkıyor
      Bağlı kal’a bassanız da bunu kapatmanın yolu yok ve iOS sonunda kendisinin daha iyi bildiğine karar verip CarPlay ağına yeniden bağlanıyor
    • Batı pazarına yönelik bir Android telefonla Çin ana karasına giderseniz daha da sinir bozucu. Çünkü internet bağlantısının olup olmadığını Google hizmetlerine erişmeye çalışarak belirliyor
      Yerel Wi‑Fi’ye bağlanınca doğal olarak Büyük Güvenlik Duvarı’nı aşamıyor ve her seferinde interneti olmayan bağlantıyı sürdürmek isteyip istemediğinizi soran bir istem çıkıyor
    • İnternet kesilince telefonla teşhis yapamamak aşırı sinir bozucu. Çünkü interneti olmayan Wi‑Fi’ye bağlı kalmıyor
      Android’in DNS tarafı da berbat; birkaç seçenek ayarlanmazsa DHCP’nin sağladığı DNS’i kullanmak istemiyor, ayarlasanız bile bazı iç DNS’leri çözümlemeyi reddediyor
    • Windows’ta da olmuyor olabilir. Windows’ta 2 kablosuz adaptör varken bile GUI üzerinden iki farklı Wi‑Fi ağına bağlanamamıştım. Terminalden denemedim
  • Firmware gereksinimlerini de kontrol etmek gerekiyor. Bazı aygıtlar enumerate edilir ama gerekli firmware yoksa ifup aşamasında başarısız olur
    Android arayüzü doğal olarak bu durumu işleyemiyor; ne olduğunu yalnızca dmesg söylüyor. CDC aygıtlarda buna gerek var mı emin değilim, ama Realtek veya Kawasaki çip tabanlı adaptörlerde bunun sık görüldüğünü hatırlıyorum
    Yine de bu Android değişikliği görece yeni olabilir. Çünkü eskiden %100 “stok” AOSP kullanan debug cihazlarında USB ağ dongle’larını sıkça kullanırdım. Ya da bu bir çekirdek değişikliği olabilir, yahut CDC sürücüsünün aygıt adını usb* olarak vermesi gibi tuhaf bir davranış olabilir. Dongle yonga setini dikkatli seçip firmware gerektirmediğinden emin olmak yeterliydi
  • Harika bir hata ayıklama yolculuğu. Gözden kaçan tek bir regex’in bütün bir cihaz sınıfını çökerttiği akış hoşuma gitti
    İlginç biçimde yakın zamanda bambaşka bir bağlamda, OpenAI’nin hizalama ve escalation sisteminde yapısal olarak benzer bir şey yaşadım. GPT-4’ün özyinelemeli mantığı içinde resmi yönlendirme escalation’ını (SR-Route_Breach_1stOrder) belgeler ve loglarla tetiklemeye çalıştım; yapısal olarak makul görünse de sonuçta yalnızca insani olmayan yanıtlar aldım
    Bir bakıma escalation’ım sistemin iç arayüzündeki regex’e eşleşmemiş gibiydi
    Tüm vakayı burada derledim: https://news.ycombinator.com/item?id=44221458
    Yapısal sınırlar ve görünmeyen arayüz sözleşmeleriyle ilgileniyorsanız düşüncelerinizi duymak isterim
  • Gerçekten tuhaf. Yaklaşık 15 USB Ethernet adaptörüm var ve hepsi sorunsuz çalışıyor
    Realtek ve AXIS benzeri birkaç farklı yonga setinin karışık olduğundan da eminim. Linux’ta sürücü gerektirmeyen ürünleri seçerseniz neredeyse her işletim sistemi veya BIOS’ta iyi çalışıyor