GNU/Linux >> Linux の 問題 >  >> Linux

proc のみを使用してローカル ネットワーク インターフェイス アドレスを取得しますか?

03 を使用して IPv4 ネットワーク構成を取得するための私のソリューション のみ:

残念ながら、これは bash です (bash のみ なし Python ではありません。しかし、これが読めることを願っています:

#!/bin/bash

# ip functions that set variables instead of returning to STDOUT

hexToInt() {
    printf -v $1 "%d\n" 0x${2:6:2}${2:4:2}${2:2:2}${2:0:2}
}
intToIp() {
    local var=$1 iIp
    shift
    for iIp ;do 
        printf -v $var "%s %s.%s.%s.%s" "${!var}" $(($iIp>>24)) \
            $(($iIp>>16&255)) $(($iIp>>8&255)) $(($iIp&255))
    done
}
maskLen() {
    local i
    for ((i=0; i<32 && ( 1 & $2 >> (31-i) ) ;i++));do :;done
    printf -v $1 "%d" $i
}

# The main loop.

while read -a rtLine ;do
    if [ ${rtLine[2]} == "00000000" ] && [ ${rtLine[7]} != "00000000" ] ;then
        hexToInt netInt  ${rtLine[1]}
        hexToInt maskInt ${rtLine[7]}
        if [ $((netInt&maskInt)) == $netInt ] ;then
            for procConnList in /proc/net/{tcp,udp} ;do
                while IFS=': \t\n' read -a conLine ;do
                    if [[ ${conLine[1]} =~ ^[0-9a-fA-F]*$ ]] ;then
                        hexToInt ipInt ${conLine[1]}
                        [ $((ipInt&maskInt)) == $netInt ] && break 3
                    fi
                done < $procConnList
            done
        fi
    fi
done < /proc/net/route 

# And finaly the printout of what's found

maskLen maskBits $maskInt
intToIp addrLine $ipInt $netInt $maskInt
printf -v outForm '%-12s: %%s\\n' Interface Address Network Netmask Masklen
printf "$outForm" $rtLine $addrLine $maskBits\ bits

出力のサンプルがあります:

Interface   : eth0
Address     : 192.168.1.32
Network     : 192.168.1.0
Netmask     : 255.255.255.0
Masklen     : 24 bits

説明:

16 をチェックするために IPV4 の整数値を使用します .

最初に 23 を読みました ルーティング構成を見つけ、ゲートウェイなしで到達可能なルートを検索します (36 ).

このようなルートの場合、this を使用してすべての接続 (TCP で見つからない場合は UDP よりも TCP) で接続を検索します ルート、最初の終点は私のホスト アドレスです。

注:これは PPP 接続では機能しません

注意 2:ネットワーク接続が開かれていない完全に静かなホストでは、これは機能しません。 54 で何かが見つかったことを確認するため .

Nota3、2016-09.23:新しい bash バージョンは 69 を使用 77 の構文 機能 .これは、18 行目のバグを意味します:スペースはしなければなりません 86 の間に存在する および 95 !!

ゲートウェイを備えた新しいバージョン

小さなパッチがあります:109 というファイルを作成すると、 前のスクリプトをコピーして、次をコマンドに貼り付けることができます:118

--- getIPv4.sh
+++ getIPv4.sh
@@ -35,13 +35,16 @@
                 done < $procConnList
             done
         fi
+    elif [ ${rtLine[1]} == "00000000" ] && [ ${rtLine[7]} == "00000000" ] ;then
+       hexToInt netGw ${rtLine[2]}
     fi
 done < /proc/net/route 

 # And finaly the printout of what's found

 maskLen maskBits $maskInt
-intToIp addrLine $ipInt $netInt $maskInt
-printf -v outForm '%-12s: %%s\\n' Interface Address Network Netmask Masklen
+intToIp addrLine $ipInt $netInt $netGw $maskInt
+printf -v outForm '%-12s: %%s\\n' \
+       Interface Address Network Gateway Netmask Masklen
 printf "$outForm" $rtLine $addrLine $maskBits\ bits

Ctrl で終了 d 、これは次のように出力されます:

patching file getIPv4.sh

たぶん

Hunk #1 succeeded at 35 with fuzz 2.

次に、スクリプトを再実行します:

getIPv4.sh
Interface   : eth0
Address     : 192.168.1.32
Network     : 192.168.1.0
Gateway     : 192.168.1.1
Netmask     : 255.255.255.0
Masklen     : 24 bits

122 の出力が見つかる場合があります 他のツールからの出力よりも解析が容易:

$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:24:1d:ce:47:05 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.121/24 brd 192.168.0.255 scope global eth0
    inet6 fe80::224:1dff:fece:4705/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
    link/ether 00:24:1d:ce:35:d5 brd ff:ff:ff:ff:ff:ff
4: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 92:e3:6c:08:1f:af brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
    inet6 fe80::90e3:6cff:fe08:1faf/64 scope link
       valid_lft forever preferred_lft forever

別のオプションはファイル 137 です .現在開いているすべての TCP セッションが表示されます。これは、要求したものとは異なりますが、十分である可能性があります。

$ cat tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 13536 1 ffff88019f0a1380 300 0 0 2 -1
   1: 00000000:1355 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 19877854 1 ffff880016e69380 300 0 0 2 -1
   2: 017AA8C0:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 13633 1 ffff88019f0a1a00 300 0 0 2 -1
   3: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 8971 1 ffff88019f0a0000 300 0 0 2 -1
   4: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 12952880 1 ffff880030e30680 300 0 0 2 -1
   5: 00000000:0539 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 14332 1 ffff88019f0a2080 300 0 0 2 -1
   6: 00000000:C000 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 14334 1 ffff88019f0a2700 300 0 0 2 -1
   7: 0100007F:0A44 00000000:0000 0A 00000000:00000000 00:00000000 00000000   119        0 51794804 1 ffff880016e6a700 300 0 0 2 -1
   8: 7900A8C0:B094 53D50E48:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 64877487 1 ffff880100502080 23 4 16 4 -1
   9: 7900A8C0:9576 537F7D4A:01BB 06 00000000:00000000 03:00000E5D 00000000     0        0 0 3 ffff880100c84600
  10: 7900A8C0:CC84 0CC181AE:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 61775908 1 ffff880198715480 35 4 11 4 -1
$ irb
irb(main):001:0> [0x79, 0x00, 0xa8, 0xc0]
=> [121, 0, 168, 192]

私のIPは141です;それを正しくするための面白い算術に注意してください。 :)


152 ネットワーク トポグラフィを保持します

すべてのアダプタのアドレスを単純に表示するには:

$ awk '/32 host/ { print f } {f=$2}' <<< "$(</proc/net/fib_trie)"
127.0.0.1
192.168.0.5
192.168.1.14

これらのアドレスのアダプタを特定するには、(a) 162 からアダプタの宛先ネットワークを調べます。 , (b) これらのネットワークを 174 のネットワークと照合します (c) それらのネットワークの下にリストされている、対応する /32 ホスト アドレスを出力します。

ここでも 185 はありません 残念ながら、かなり厄介な 197 アプローチ:

#!/bin/bash

ft_local=$(awk '$1=="Local:" {flag=1} flag' <<< "$(</proc/net/fib_trie)")

for IF in $(ls /sys/class/net/); do
    networks=$(awk '$1=="'$IF'" && $3=="00000000" && $8!="FFFFFFFF" {printf $2 $8 "\n"}' <<< "$(</proc/net/route)" )
    for net_hex in $networks; do
            net_dec=$(awk '{gsub(/../, "0x& "); printf "%d.%d.%d.%d\n", $4, $3, $2, $1}' <<< $net_hex)
            mask_dec=$(awk '{gsub(/../, "0x& "); printf "%d.%d.%d.%d\n", $8, $7, $6, $5}' <<< $net_hex)
            awk '/'$net_dec'/{flag=1} /32 host/{flag=0} flag {a=$2} END {print "'$IF':\t" a "\n\t'$mask_dec'\n"}' <<< "$ft_local"
    done
done

exit 0

出力:

eth0:     192.168.0.5
          255.255.255.0

lo:       127.0.0.1
          255.0.0.0

wlan0:    192.168.1.14
          255.255.255.0

既知の制限:

このアプローチは、他のホスト アドレスとネットワークを共有するホスト アドレスに対しては確実に機能しません。このネットワークの一意性の喪失により、fib_trie から正しいホスト アドレスを決定することができなくなります。これは、これらのアドレスの順序がルートのネットワークの順序と必ずしも一致しないためです。

そうは言っても、最初に同じネットワークに属する複数のホストアドレスが必要な理由がわかりません。したがって、ほとんどのユース ケースでは、このアプローチは問題なく機能するはずです。


/proc/net/if_inet6 の IPv4 類似物はありません

ifconfig は:

fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)
ioctl(fd, SIOCGIFCONF, ...)

次のようなものが得られます:

ioctl(4, SIOCGIFCONF, {120, {{"lo", {AF_INET, inet_addr("127.0.0.1")}}, {"eth0", {AF_INET, inet_addr("10.6.23.69")}}, {"tun0", {AF_INET, inet_addr("10.253.10.151")}}}})

Linux
  1. ネットワークのトラブルシューティングにSSツールを使用する

  2. アクセスできないネットワーク上にあるサービス/サーバーにアクセスする方法(SSHトンネルを使用)

  3. Ssh –ローカルネットワークの外部からのGoogle認証システムのみが必要ですか?

  1. クラウドネットワークインターフェイスをクラウドサーバーに追加します

  2. Linux でインターフェイスの IP アドレスを取得する

  3. Python:Linux でローカル インターフェイス/IP アドレスのデフォルト ゲートウェイを取得する

  1. DHCP を使用して、1 つのネットワーク カードで 2 つの IP アドレスを取得する

  2. ネットワークにないデバイスの MAC アドレスを取得する方法

  3. ローカル ネットワークからのみ Apache 仮想ホストへのアクセスを許可する