OpenWrt获取网关IP

OpenWrt获取网关IP

一、概述

OpenWrt也是Linux,题目其实也可以叫做“Linux获取网关IP”。一般想得知网关IP,都是因为本地接口设置了DHCP,网关IP,大多数也即是DHCP Server的IP(DHCP Relay除外)。

二、一般方法汇总

1、猜

没错,是猜,因为网关IP一般为XXX.XXX.XXX.1,所以ifconfig出来的接口IP,就可以推测出网关的IP。

2、查路由表

当连接建立之后,本地一般会生成默认的路由,因此查路由表,就可以直接得知网关IP。
此类方法有很多,比如一些命令,以及以这些命令为基础制作的脚本
1)route -n
2)ip route show
3)netstat -r
。。。
还有一些其他命令,如traceroute等。

3、写代码获取内核消息

是方法2的进阶,除了利用命令写脚本,也可以通过与内核通信,获取一些信息
如果这个博文所转载的http://blog.csdn.net/liangyamin/article/details/7242048,通过NLMSG从内核获取路由信息,本质还是在查路由表,

4、查看resolv.conf

针对dhcp,一般如果使用了dnsmasq,会记录一些信息如网关、dns等,这些信息一般会在 resolv.conf/resolv.conf.auto等文件中,而这个文件大部会在/var/resolv.conf、/etc /resolv.conf等目录,具体可以查看dhcp或dnsmasq的配置文件。

三、解析DHCP消息

这里想着重提一下从dhcp消息中,获取dhcp server ip(即网关IP)。DHCP的详细原理这里就不在冗述了,直接看图

DHCP原理图

本端作为dhcp client,从收到dhcp offer开始,就已经知道dhcp server的IP,只要解析这个消息即可。
dhcp offer报文格式中的Siaddr字段内容,即dhcp server IP.

Siaddr: IP address of next server to use in bootstrap.

这个才是最根本的源头。
那么问题来了,dhcp程序有很多,比如常用的有dhclient或busybox中的udhcpc等,如何从进程中获得dhcp Packet的内容呢?
一种方式是打补丁,这些代码都是开源的,如果开发的系统允许自行修改,可以干脆修改dhcp源码增加一些输出。
另外发现dhcp程序的参数支持script运行,比如udhcpc的-s参数
-s,--script PROG   Run PROG at DHCP events (default /usr/share/udhcpc/default.script)
以OpenWrt为例

root@OpenWrt:/# ps |grep dhcp
 1384 root      1516 S    udhcpc -S -p /var/run/udhcpc-ath01.pid -s /lib/netifd/dhcp.script -f -t 0 -i ath01 -C
 3212 root      1500 S    grep dhcp
root@OpenWrt:/#

/lib/netifd/dhcp.script的内容:

root@OpenWrt:/# cat /lib/netifd/dhcp.script
#!/bin/sh
[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1

. /lib/functions.sh
. /lib/netifd/netifd-proto.sh

set_classless_routes() {
    local max=128
    local type
    while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do
        proto_add_ipv4_route "${1%%/*}" "${1##*/}" "$2"
        max=$(($max-1))
        shift 2
    done
}

setup_interface () {
    proto_init_update "$IFNAME" 1
    proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}"
    # TODO: apply $broadcast

    for i in $router; do
        echo "i=$i" > /dev/console
        proto_add_ipv4_route 0.0.0.0 0 "$i"
    done

    # CIDR STATIC ROUTES (rfc3442)
    [ -n "$staticroutes" ] && set_classless_routes $staticroutes
    [ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes

    for dns in $dns; do
        proto_add_dns_server "$dns"
    done
    for domain in $domain; do
        proto_add_dns_search "$domain"
    done
    proto_send_update "$INTERFACE"

    # TODO
    # [ -n "$ntpsrv" ] &&     change_state network "$ifc" lease_ntpsrv "$ntpsrv"
    # [ -n "$timesvr" ] &&     change_state network "$ifc" lease_timesrv "$timesvr"
    # [ -n "$hostname" ] &&    change_state network "$ifc" lease_hostname "$hostname"
    # [ -n "$timezone" ] &&     change_state network "$ifc" lease_timezone "$timezone"
}

deconfig_interface() {
    proto_init_update "*" 0
    proto_send_update "$INTERFACE"
}

case "$1" in
    deconfig)
        deconfig_interface
    ;;
    renew|bound)
        setup_interface
    ;;
esac

echo "4=$4" > /dev/console

# user rules
[ -f /etc/udhcpc.user ] && . /etc/udhcpc.user

exit 0
root@OpenWrt:/#

经测试$router的值就是Siaddr的值。


本文章由作者:佐须之男 整理编辑,原文地址: OpenWrt获取网关IP
本站的文章和资源来自互联网或者站长的原创,按照 CC BY -NC -SA 3.0 CN协议发布和共享,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资 源请尽快联系站长,我们会在24h内删除有争议的资源。欢迎大家多多交流,期待共同学习进步。

相关推荐