# Detect DHCP Network Changes?



## kev (Dec 15, 2021)

I have a machine running FreeBSD 12.3 and I am looking for a way to monitor network changes through a shell script, specifically related to the network interfaces.

Some examples of things that I would like to detect are:

When a network interface changes status (e.g. from active to no carrier)
When a new DHCP IP addressed is assigned to a network interface
Is this achievable in FreeBSD?


----------



## SirDice (Dec 15, 2021)

You could use some clever devd.conf(5) rules to detect LINK_UP and LINK_DOWN. And use a dhclient-script(8) hook to detect DHCP changes.


----------



## Phishfry (Dec 16, 2021)

I would like more information.

Do you get an IP from a DHCP server (like your ISP) and you want to monitor that connection and interface?

Or Perhaps you are running your own DHCP server and you want to know when your DHCP server is handing out leases?


----------



## Phishfry (Dec 16, 2021)

There is a file based approach you could use for a client to monitor DHCP lease assignment.

You could have security/tripwire monitor your lease file.
For example whenever /var/db/dhclient.leases.em0 is wrote to tripwire would trigger a report.
You would setup tripwire to run via cron and run an integrity test. It would flag the change to lease file.

Note: em0 is my interface name for dhclient leases. Please substitute your interface name.


----------



## Phishfry (Dec 16, 2021)

I am sure there are easier ways of monitoring a single lease file and check interface status with a scheduled ping.

So yes FreeBSD can monitor itself. Have you tried a basic script?


----------



## Phishfry (Dec 16, 2021)

Many times when I need to monitor something I use FreeBSD resources to accomplish that.
For example look at /etc/periodic/daily/420.status-network
You can scrape parts of that for the beginning of a new script.









						Ping or whatever script to reconnect a server when it loses connectivity
					

Hi i need help from you guys, im looking for a simple ping or whatever script to keep a server reconnected to a network when it loses leases (when using dhcp) or can not keep connected to the default route. Any ideas? i can not find anything useful on google x(




					forums.freebsd.org


----------



## kev (Dec 16, 2021)

SirDice said:


> You could use some clever devd.conf(5) rules to detect LINK_UP and LINK_DOWN. And use a dhclient-script(8) hook to detect DHCP changes.


I believe that this suggestion will work for me. I will attempted to implement. I'll be sure to drop back to this forum if I have another question.




Phishfry said:


> I would like more information.
> 
> Do you get an IP from a DHCP server (like your ISP) and you want to monitor that connection and interface?
> 
> Or Perhaps you are running your own DHCP server and you want to know when your DHCP server is handing out leases?


I am receiving IPs from a DHCP server. 



Phishfry said:


> There is a file based approach you could use for a client to monitor DHCP lease assignment.
> 
> You could have security/tripwire monitor your lease file.
> For example whenever /var/db/dhclient.leases.em0 is wrote to tripwire would trigger a report.
> ...


My aim was to achieve this natively within FreeBSD without installing any additional packages.



Phishfry said:


> Many times when I need to monitor something I use FreeBSD resources to accomplish that.
> For example look at /etc/periodic/daily/420.status-network
> You can scrape parts of that for the beginning of a new script.
> 
> ...


Perhaps this suggestion may work for me as well. Again, if I have anymore questions I'll be sure to ask.

If there are any more suggestions others may have, please continue to add them.

Thanks all!


----------



## kev (Dec 16, 2021)

SirDice said:


> You could use some clever devd.conf(5) rules to detect LINK_UP and LINK_DOWN. And use a dhclient-script(8) hook to detect DHCP changes.


So I implemented this suggestion. From my results, I can successfully detect a "LINK_DOWN" by unplugging my attached ethernet cord, however I can not detect a "LINK_UP" when the cable is reattached. Is this the wrong way to simulate a "LINK_UP"? If so, the detaching and reattaching of the ethernet cord is in essence what I would like to detect.


----------



## kev (Dec 17, 2021)

To add on to my previous question, I also attempted to use a dhclient-script(8) hook to detect DHCP changes. I have a /etc/dhclient-exit-hooks directory. In there it contains a simple shell script to echo to the command line when an event occurs, however it does not seem to execute when I disconnect and reconnect an ethernet cord. Any ideas as to why?


```
#!/bin/sh

if [[ “$interface” = “em0”]] || [[“$interface” = “em1” ]] ; then
 case “$reason” in BOUND|RENEW|REBIND|REBOOT|EXPIRE|FAIL|TIMEOUT)
            echo Event occured
       ;;
       esac
fi
```


----------



## covacat (Dec 17, 2021)

for one it uses bash constructs like [[ which don't work in posix sh


----------



## kev (Dec 17, 2021)

covacat said:


> for one it uses bash constructs like [[ which don't work in posix sh



Noted. I've made the change to use bash, but still no luck.


----------



## covacat (Dec 17, 2021)

kev said:


> I have a /etc/dhclient-exit-hooks directory.


you need a file not a dir
/etc/dhclient-exit-hooks should be your script
put something like this at the top for more logging

```
#!/bin/sh
exec >>/tmp/dhclient.log 2>&1
date "+====== %Y-%m-%d %H:%M:%S ================"
set -x
```


----------



## kev (Dec 20, 2021)

covacat said:


> you need a file not a dir
> /etc/dhclient-exit-hooks should be your script
> put something like this at the top for more logging



Ahhh, I see. Thanks for the clarification. I feel as if I am very close to achieving my goal.

So after making that correction. my dhclient-exit-hooks script seems to work, somewhat. It seems to detect when I connect an ethernet cable and establish a connection, however it does not detect when I remove it. On the contrary, when using the devd.conf rules, it seems to detect when the ethernet cable is removed, but not re-inserted. When both are implemented together, they accomplish what I am trying to achieve. However I feel as one of these implementations should be able to handle what I need., not both. If I am wrong please let me know. Worse case scenario is that I implement both. Below are both scripts.

For some clarification, I am testing this by running an executable called "displayip" which simply makes an ifconfig call and tells me the status and ip (if there is one) of the relative network interface. In the dhclient-exit-hooks script, I added pretty much all of the available reasons as so that the network interface status information is kept up to date in real time. Could that be the source of my issue?

Also the same logic I applied with the devd.conf rules. I added both "ATTACH" and "DETACH" as types because my initial testing with "LINK_UP" and "LINK_DOWN" only resulted in "LINK_DOWN" working.


dhclient-exit-hooks:

```
#!/bin/bash
exec >>/tmp/dhclient.log 2>&1
date "+==============%Y-%m-%d %H:%M:%S================"
set -x

if [ "${interface}" = "em0" ] || [ "${interface}" = "em1" ] || [ "${interface}" = "igb0" ] || [ "${interface}" = "igb1" ]; then
    case "${reason}" in BOUND|RENEW|REBIND|REBOOT|EXPIRE|FAIL|TIMEOUT|MEDIUM|PREINIT)
        /usr/home/develop/Display/displayip
    ;;
    esac
fi
```

displayip.conf:

```
notify 0 {
    match "system"        "IFNET";
    match "subsystem"    "(em0|em1|igb0|igb1)";
    match "type"        "LINK_DOWN";
    action                "/usr/home/develop/Display/displayip";

notify 0 {
    match "system"        "IFNET";
    match "subsystem"    "(em0|em1|igb0|igb1)";
    match "type"        "LINK_UP";
    action                 "/usr/home/develop/Display/displayip";
};

notify 0 {
    match "system"        "IFNET";
    match "subsystem"    "(em0|em1|igb0|igb1)";
    match "type"        "ATTACH";
    action                "/usr/home/develop/Display/displayip";
};

notify 0 {
    match "system"        "IFNET";
    match "subsystem"    "(em0|em1|igb0|igb1)";
    match "type"        "DETACH";
    action                "/usr/home/develop/Display/displayip";
}
```


----------



## Vull (Dec 20, 2021)

kev said:


> ...<snip
> 
> ```
> #!/bin/bash
> ...



I don't think this shebang line will work on FreeBSD; it should be something like `#!/usr/local/bin/bash`

I'm not sure about the exact filespec because I only use `#!/bin/sh`


----------



## covacat (Dec 20, 2021)

Vull said:


> don't think this shebang line will work on FreeBSD; it should be something like `#!/usr/local/bin/bash`
> 
> I'm not sure about the exact filespec because I only use `#!/bin/sh`


normally it won't
but the above script does not exec the "hook script" it sources it so it does not matter


----------

