Ситуация — домашний компьютер, доступ в интернет только через 2G (GSM/EDGE) мобильные сети. Медленно и противно.
При этом, в наличии несколько USB-модемов, несколько смартфонов и соответственно несколько SIM-карт с доступом в интернет.
Для того, чтобы ускорить загрузку сайтов (и файлов, в многопоточном режиме), было принято решения подключить к компьютеру все модемы/смартфоны и агрегировать все соединения, путем распределения запросов между ними.
А для автоматизации этого процесса, потребовалось динамически получить адреса шлюзов (gateway) на каждом из подключенных интерфейсов.
Причем, разные модемы/смартфоны подключаются разным методом — некоторые из них ppp0-1-2 и т.д, другие usb0-1-2, а иные enp0s26u1u3, wwp0s29u1u5i2 и т.д.
Сразу хочу отметить — задача была решена.
Само распределение организуется достаточно просто — путем добавление собственных маршрутов (ip route add), а вот получить текущие адреса шлюзов некоторых интерфейсов оказалось задачкой не тривиальной.
Команда route -n выдаст информацию только о дефолтном шлюзе.
Команда ifconfig покажет шлюз для соединений типа ppp, в качестве destination, а вот для иных интерфейсов будет отображен broadcast- широковещательный IP-адрес.
Гугл, привел на форумы невероятно умных людей, где кто-то задает аналогичный вопрос, а невероятно умные люди отвечают, что способов узнать текущий шлюз вагон и маленькая тележка, но ни один из этих невероятно умных людей так и не предложил готового работающего способа.
Пришлось отбросить лень и самостоятельно углубиться в вопрос.
Способ traceroute -i интерфейс —max-hops=1 8.8.8.8 был отброшен сразу, поскольку нередки ситуации вида
[****p@localhost ~]$ sudo traceroute -i ppp0 --max-hops=1 8.8.8.8 traceroute to 8.8.8.8 (8.8.8.8), 1 hops max, 60 byte packets 1 * * * [****p@localhost ~]$
Далее, была даже мысль раскопать как следует NetworkManager и виджет отображающий сетевые соединения — ведь они эту информацию имеют и отображают! Нелегкий путь с использованием костылей… и он был отброшен.
А потом пришло озарение.
Информация о шлюзах интерфейсов сохраняется в кеше ARP, соответственно получить адреса таких шлюзов можно так:
arp -i интерфейс
Так:
ip neigh show dev интерфейс
Ну и чтобы получить IP в готовом варианте, я это реализовал так:
P2=`ip neigh show dev интерфейс | grep -E «REACHABLE|STALE» | awk {‘print $1’}`
#теперь $P2 присовено значение в виде IP шлюза интерфейса
echo $P2
Таким образом, остается распарсить вывод команды ifconfig и если вместо destination имеем broadcast — получить IP-адрес шлюза вышеприведенным кодом.