progpib/vendortools/nfcli.py

358 lines
10 KiB
Python
Raw Normal View History

2020-09-26 16:54:16 -05:00
#!/usr/bin/env python3
2020-09-09 00:06:47 -05:00
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__":
2020-09-26 16:54:16 -05:00
main()