#!/usr/bin/env python3 import getopt import socket import sys import os import platform from nfutil import * from enumip import * #----------------------------------------------------------------------------- def usage(): print print "Usage: nfcli --list --eth_addr=ADDR --ip_type=TYPE --ip_addr=IP, --netmask=MASK, --gateway=GW" print "Search and configure Prologix GPIB-ETHERNET Controllers." print "--help : display this help" print "--list : search for controllers" print "--eth_addr=ADDR : configure controller with Ethernet address ADDR" print "--ip_type=TYPE : set controller ip address type to TYPE (\"static\" or \"dhcp\")" print "--ip_addr=IP : set controller address to IP" print "--netmask=MASK : set controller network mask to MASK" print "--gateway=GW : set controller default gateway to GW" #----------------------------------------------------------------------------- def enumIp(): if platform.system() in ('Windows', 'Microsoft'): return socket.gethostbyname_ex(socket.gethostname())[2]; return enumIpUnix() #----------------------------------------------------------------------------- def ValidateNetParams(ip_str, mask_str, gw_str): try: ip = socket.inet_aton(ip_str) except: print "IP address is invalid." return False try: mask = socket.inet_aton(mask_str) except: print "Network mask is invalid." return False try: gw = socket.inet_aton(gw_str) except: print "Gateway address is invalid." return False # Validate network mask # Convert to integer from byte array mask = struct.unpack("!L", mask)[0] # Exclude restricted masks if (mask == 0) or (mask == 0xFFFFFFFF): print "Network mask is invalid." return False # Exclude non-left-contiguous masks if (((mask + (mask & -mask)) & 0xFFFFFFFF) != 0): print "Network mask is not contiguous." return False # Validate gateway address octet1 = ord(gw[0]) # Convert to integer from byte array gw = struct.unpack("!L", gw)[0] # Exclude restricted addresses # 0.0.0.0 is valid if ((gw != 0) and ((octet1 == 0) or (octet1 == 127) or (octet1 > 223))): print "Gateway address is invalid." return False # Validate IP address octet1 = ord(ip[0]) # Convert to integer from byte array ip = struct.unpack("!L", ip)[0] # Exclude restricted addresses if ((octet1 == 0) or (octet1 == 127) or (octet1 > 223)): print "IP address is invalid." return False # Exclude subnet network address if ((ip & ~mask) == 0): print "IP address is invalid." return False # Exclude subnet broadcast address if ((ip & ~mask) == (0xFFFFFFFF & ~mask)): print "IP address is invalid." return False return True #----------------------------------------------------------------------------- #def ValidateAddress(address): # if address is None: # return False # parts = address.split(".") # if len(parts) != 4: # return False # try: # for item in parts: # if not 0 <= int(item) <= 255: # return False # except: # return False # return True #----------------------------------------------------------------------------- def main(): invalid_args = False showhelp = False search = False ip_type = None ip_addr = None netmask = None gateway = None eth_addr = None try: opts, args = getopt.getopt(sys.argv[1:], '', ['help', 'list', 'eth_addr=', 'ip_type=', 'ip_addr=', 'netmask=', 'gateway=']) except getopt.GetoptError, err: print str(err) sys.exit(1) # Check for unparsed parameters if len(args) != 0: usage() sys.exit(1) for o, a in opts: if o == "--help": showhelp = True elif o == "--list": search = True elif o == "--eth_addr": eth_addr = a elif o == "--ip_type": ip_type = a elif o == "--ip_addr": ip_addr = a elif o == "--netmask": netmask = a elif o == "--gateway": gateway = a if (len(opts) == 0) or (showhelp): usage() sys.exit(1) if search: if not eth_addr is None: print "--list and --eth_addr are not compatible." invalid_args = True if not ip_type is None: print "--list and --ip_type are not compatible." invalid_args = True if not ip_addr is None: print "--list and --ip_addr are not compatible." invalid_args = True if not netmask is None: print "--list and --netmask are not compatible." invalid_args = True if not gateway is None: print "--list and --gateway are not compatible." invalid_args = True else: try: eth_addr = eth_addr.strip().replace(":", "").replace("-", "") eth_addr = eth_addr.decode('hex') except: print "Invalid Ethernet address." sys.exit(1) if len(eth_addr) != 6: print "Invalid Ethernet address." sys.exit(1) if ip_type in ["Static", "static"]: ip_type = NF_IP_STATIC elif ip_type in ["Dynamic", "dynamic", "Dhcp", "dhcp"]: ip_type = NF_IP_DYNAMIC else: print "--ip_type must be 'static' or 'dhcp'." sys.exit(1) if ip_type == NF_IP_STATIC: if not ValidateNetParams(ip_addr, netmask, gateway): invalid_args = True # if not ValidateIP(ip_addr): # print "Invalid, or no, IP address specified." # invalid_args = True # if not ValidateIP(netmask): # print "Invalid, or no, netmask specified." # invalid_args = True # if not ValidateIP(gateway): # print "Invalid, or no, gateway address specified." # invalid_args = True else: if ip_addr is None: ip_addr = "0.0.0.0" else: print "--ip_addr not allowed when --ip_type=dhcp." invalid_args = True if netmask is None: netmask = "0.0.0.0" else: print "--netmask not allowed when --ip_type=dhcp." invalid_args = True if gateway is None: gateway = "0.0.0.0" else: print "--gateway not allowed when --ip_type=dhcp." invalid_args = True if invalid_args: sys.exit(1) global seq sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) iplist = enumIp(); if len(iplist) == 0: print "Host has no IP address." sys.exit(1) devices = {} for ip in iplist: print "Searching through network interface:", ip s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) port = 0 try: s.bind((ip, port)) except socket.error, e: print "Bind error on send socket:", e sys.exit(1) port = s.getsockname()[1] r = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) r.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) r.setblocking(1) r.settimeout(0.100) try: r.bind(('', port)) except socket.error, e: print "Bind error on receive socket:", e sys.exit(1) d = Discover(s, r) print for k in d: d[k]['host_ip'] = ip devices[k] = d[k] s.close() r.close() if search: print print "Found", len(devices), "Prologix GPIB-ETHERNET Controller(s)." for key in devices: PrintDetails(devices[key]) print else: if eth_addr in devices: print "Updating network settings of Prologix GPIB-ETHERNET Controller", FormatEthAddr(eth_addr) device = devices[eth_addr] if (device['ip_type'] == NF_IP_STATIC) or (ip_type == NF_IP_STATIC): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) port = 0 try: s.bind((device['host_ip'], port)) except socket.error, e: print "Bind error on send socket:", e sys.exit(1) port = s.getsockname()[1] r = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) r.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) r.setblocking(1) r.settimeout(0.100) try: r.bind(('', port)) except socket.error, e: print "Bind error on receive socket:", e sys.exit(1) result = Assignment(s, r, eth_addr, ip_type, ip_addr, netmask, gateway) print if len(result) == 0: print "Network settings update failed." else: if result['result'] == NF_SUCCESS: print "Network settings updated successfully." else: print "Network settings update failed." else: print "Prologix GPIB-ETHERNET Controller", FormatEthAddr(eth_addr), "already configured for DHCP." else: print "Prologix GPIB-ETHERNET Controller", FormatEthAddr(eth_addr), "not found." #----------------------------------------------------------------------------- if __name__ == "__main__": main()