Home > Net >  Given an IP address on local linux machine, how check whether it is occuppied?
Given an IP address on local linux machine, how check whether it is occuppied?

Time:12-10

I know one IP can be used by multiple processes, but my use case requires that an IP is use exclusively by one process.

I have multiple IPs on my machine (ubuntu), and multiple running processes are using this IPs as tcp clients. These IPs have the same routing setting (except metric). Each process is using one of the IPs. The problem is I have a manually assign which process using which IP.

I'm wondering whether I can make this process automatic. When a process is started, it checks the given ip list, and use the first that is not occupied. Is this possible?

CodePudding user response:

For each possible IP you want to use, attempt to bind your socket to that IP along with a known port that all clients will use. If the bind call is successful, that socket will be only one using that IP and port.

If the bind call fails with error code EADDRINUSE, you know some other socket is bound to that IP and port. Then you can try the next IP in the list.

CodePudding user response:

Setup: create interface bridge0 with 5 ip address

ip link add name bridge0 type bridge
ip link set bridge0 up
ip addr add 192.168.1.5/24 dev bridge0
ip addr add 192.168.1.6/24 dev bridge0
ip addr add 192.168.1.7/24 dev bridge0
ip addr add 192.168.1.8/24 dev bridge0
ip addr add 192.168.1.9/24 dev bridge0

To see available IP addresses:

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xxxx brd ff:ff:ff:ff:ff:ff
    inet xxxx/24 brd xxxx scope global dynamic noprefixroute wlan0
       valid_lft 299sec preferred_lft 299sec
    inet6 xxxx/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether xxxx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.5/24 scope global bridge0
       valid_lft forever preferred_lft forever
    inet 192.168.1.6/24 scope global secondary bridge0
       valid_lft forever preferred_lft forever
    inet 192.168.1.7/24 scope global secondary bridge0
       valid_lft forever preferred_lft forever
    inet 192.168.1.8/24 scope global secondary bridge0
       valid_lft forever preferred_lft forever
    inet 192.168.1.9/24 scope global secondary bridge0
       valid_lft forever preferred_lft forever
    inet6 fe80::6c8e:f0ff:fe1f:6779/64 scope link 
       valid_lft forever preferred_lft forever

To only get the available IP addresses:

$ ip addr | grep inet | grep bridge0
    inet 192.168.1.5/24 scope global bridge0
    inet 192.168.1.6/24 scope global secondary bridge0
    inet 192.168.1.7/24 scope global secondary bridge0
    inet 192.168.1.8/24 scope global secondary bridge0
    inet 192.168.1.9/24 scope global secondary bridge0

or:

$ ip addr | grep inet | grep bridge0 | awk '{print $2}'
192.168.1.5/24
192.168.1.6/24
192.168.1.7/24
192.168.1.8/24
192.168.1.9/24

Then you can use ss to see which port is used:

$ ss -ltn
State        Recv-Q       Send-Q             Local Address:Port               Peer Address:Port       Process       
LISTEN       0            80                       0.0.0.0:3306                    0.0.0.0:*                        
LISTEN       0            128                      0.0.0.0:22                      0.0.0.0:*                        
LISTEN       0            5                      127.0.0.1:52698                   0.0.0.0:*                        
LISTEN       0            80                          [::]:3306                       [::]:*                        
LISTEN       0            511                            *:80                            *:*                        
LISTEN       0            50                             *:1716                          *:*                        
LISTEN       0            128                         [::]:22                         [::]:*                        
LISTEN       0            256                            *:3128                          *:*

or:

$ ss -ltn | awk '{print $4}'
Local
0.0.0.0:3306
0.0.0.0:22
127.0.0.1:52698
[::]:3306
*:80
*:1716
[::]:22
*:3128

Then you can parse the output to decide which port is still unused

  • Related