Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect IP address change programmatically in Linux?

Tags:

c++

linux

Is there a way to detect IP address changes on the local machine in Linux programmatically using C++?

like image 438
Amit Wadhwa Avatar asked Feb 23 '09 23:02

Amit Wadhwa


People also ask

How do I know if my IP address has been changed?

To determine when your IP address may change or if it already has, start by determining your current IP address. You can do this by searching “what is my IP address” or using free tools like WhatIsMyIP.com. Then, compare the returned address to the examples below.

Does Linux change IP address?

Luckily for you, Linux has multiple ways of changing your IP address, whether you want it to be dynamic or static. You will see how it is possible to have multiple IP addresses for a single machine and how you can assign IP addresses to virtual network adapters.

How check DHCP or static IP Linux?

There's no simple command that you can run to determine whether the IP address on a Linux system is assigned by DHCP or static. If it changes when the system restarts, it's clearly dynamically assigned, but even a dynamic address has some resistance to change. The best way is to look at the configuration file.


2 Answers

here you go.. this does it without polling.

it only listens for RTM_NEWADDR but it should be easy to change to support RTM_DELADDR if you need

#include <stdio.h> #include <string.h> #include <netinet/in.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <net/if.h>  int main() {     struct sockaddr_nl addr;     int sock, len;     char buffer[4096];     struct nlmsghdr *nlh;      if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {         perror("couldn't open NETLINK_ROUTE socket");         return 1;     }      memset(&addr, 0, sizeof(addr));     addr.nl_family = AF_NETLINK;     addr.nl_groups = RTMGRP_IPV4_IFADDR;      if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {         perror("couldn't bind");         return 1;     }      nlh = (struct nlmsghdr *)buffer;     while ((len = recv(sock, nlh, 4096, 0)) > 0) {         while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {             if (nlh->nlmsg_type == RTM_NEWADDR) {                 struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);                 struct rtattr *rth = IFA_RTA(ifa);                 int rtl = IFA_PAYLOAD(nlh);                  while (rtl && RTA_OK(rth, rtl)) {                     if (rth->rta_type == IFA_LOCAL) {                         char name[IFNAMSIZ];                         if_indextoname(ifa->ifa_index, name);                         char ip[INET_ADDRSTRLEN];                         inet_ntop(AF_INET, RTA_DATA(rth), ip, sizeof(ip));                         printf("interface %s ip: %s\n", name, ip);                     }                     rth = RTA_NEXT(rth, rtl);                 }             }             nlh = NLMSG_NEXT(nlh, len);         }     }     return 0; } 
like image 89
Danny Dulai Avatar answered Sep 29 '22 00:09

Danny Dulai


In C, to get the current IP I use:

    int s;     struct ifreq ifr = {};      s = socket(PF_INET, SOCK_DGRAM, 0);      strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));      if (ioctl(s, SIOCGIFADDR, &ifr) >= 0)         printf("%s\n",           inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); 

Replace "eth0" with the interface you're looking at. All you now need to do is poll for a change.

like image 38
ste Avatar answered Sep 28 '22 23:09

ste