/ Notification de changement IP
Notification de changement IP
332x
Facebook Twitter Google+
 

Notifier un serveur de son changement d'adresse IP

Il arrive parfois que nous avons un équipement qui change d'adresse IP, mais dont nous désirons connaître ce dernier sans avoir nécessairement accès au routeur, au DHCP ou à un autre service tier. Voici donc un script qui sert à notifier, dans une base de données, un changement au niveau de l'adresse IP. Je vous laisse deviner le contenu de la stored procedure utilisée... si vous comprenez le contenu de ce blogue, c'est que vous êtes sans doute en mesure de comprendre cette partie!

Le script ne fait rien de très compliqué, à part de s'assurer de s'exécuter la plupart du temps (et même en cas d'exception), il obtient son adresse IP, fait toujours une mise à jour la première fois et les mises à jour subséquentes n'auront lieu que lorsque l'adresse aura changée.Idéalement, ce script devrait être lancé automatiquement au démarrage du périphérique, en utilisant systemctl, par exemple.

updateip.py

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env python
import struct
import socket
import fcntl
import getopt
import sys
import os
import time

CFG_DATABASE_IP = "192.168.10.4"
CFG_DATABASE_USER = "user"
CFG_DATABASE_PWD = "passwd"
CFG_DATABASE_NAME = "iplist"

CFG_DEFAULT_IP_VALIDATION = 15


def setargs(argv):
    global s_dev

    try:
        opts, args = getopt.getopt(argv, "h:i:", [])

        for opt, arg in opts:
            if opt == '-h':
                help_exit()
            elif opt in "-i":
                s_dev = arg
    except getopt.GetoptError:
        help_exit()

    if s_dev is None:
        help_exit()


def help_exit():
    print(get_name() + ' -i <eth> [-h]')
    sys.exit()


def get_name():
    return os.path.basename(sys.argv[0])


def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    try:
        s_ip = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915,
                struct.pack('256s', ifname[:15]))[20:24])
    except IOError:
        s_ip = None

    return s_ip


def get_mac_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
    return ':'.join(['%02x' % ord(char) for char in info[18:24]]).upper()


def get_netmask(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    try:
        s_mask = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 35099, 
                    struct.pack('256s', ifname))[20:24])
    except IOError:
        s_mask = None

    return s_mask


def check_ip(h_eth, s_dev):
    s_ip = get_ip_address(s_dev)
    s_mac = get_mac_address(s_dev)
    s_mask = get_netmask(s_dev)

    # we do more validation if we are waiting for interface to become ready...
    if s_ip is None or s_mac is None or s_mask is None:
        time.sleep(30)
        return True

    if h_eth['ip'] != s_ip or h_eth['mac'] != s_mac or h_eth['mask'] != s_mask:
        h_eth['ip'] = s_ip
        h_eth['mac'] = s_mac
        h_eth['mask'] = s_mask

        conn = pg8000.connect(host=CFG_DATABASE_IP, user=CFG_DATABASE_USER, 
                              password=CFG_DATABASE_PWD, 
                              database=CFG_DATABASE_NAME, socket_timeout=5)

        cursor = conn.cursor()
        cursor.execute("SELECT FROM sp_update_ip(%s, %s, %s)", 
                                                          [s_mac, s_ip, s_mask])

        cursor.close()
        conn.commit()

    return False


if __name__ == '__main__':
    s_dev = None
    h_eth = dict(ip=None, mac=None, mask=None)

    setargs(sys.argv[1:])

    while True:
        try:
            if check_ip(h_eth, s_dev):
                continue

        except pg8000.InterfaceError as err:
            print("Database error!")
        except IOError as (errno, strerror):
            print("I/O error({0}): {1}".format(errno, strerror))
        except ValueError:
            print("Could not convert data to an integer.")
        except:
            print("Unexpected error : ", sys.exc_info()[0])
            # raise

        time.sleep(60 * CFG_DEFAULT_IP_VALIDATION)

Loading... Veuillez patienter...