nodescan2.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. # -*- coding: utf-8 -*-
  2. """
  3. Valid-License-Identifier: GPL-2.0-only
  4. SPDX-URL: https://spdx.org/licenses/GPL-2.0-only.html
  5. (c) 2012 micha@librelight.de
  6. """
  7. import time
  8. import json
  9. import socket, struct
  10. import sys
  11. import os
  12. import _thread as thread
  13. import copy
  14. import random
  15. import traceback
  16. from cprint import cprint
  17. if __name__ == "__main__":
  18. sys.stdout.write("\x1b]2;Nodescan\x07")
  19. def UDP_Socket(bind=False,ip='',port=6454):
  20. sock = False
  21. try:
  22. print(sys._getframe().f_code.co_name,"BIND",(ip,port,bind),"?")
  23. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  24. sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
  25. if bind:
  26. sock.bind((ip, port))
  27. print(sys._getframe().f_code.co_name,"BIND",(ip,port),"OK")
  28. except socket.error as e:
  29. cprint(" Socket 6454 ", "ERR: {0} ".format(e.args),color="red")
  30. sock = False
  31. return sock
  32. def ArtPoll(sock=None,ip="2.255.255.255",port=6454):
  33. print("ArtPoll",ip,port)
  34. if not sock:
  35. sock=UDP_Socket()
  36. #port=6454
  37. #ip="2.255.255.255"
  38. PKG=b'Art-Net\x00\x00 \x00\x0e\x06\x00'
  39. print(" -> SEND:",[PKG])
  40. sock.sendto(PKG,(ip,port)) # ArtPol / ping
  41. sock.close()
  42. time.sleep(1)
  43. def convert_mac(MAC):
  44. #MAC = data[201:201+6]
  45. _MAC = []
  46. for x in MAC:
  47. #x = hex(ord(x))[2:]
  48. x = hex(x)[2:]
  49. x = x.rjust(2,"0")
  50. _MAC.append(x)
  51. _MAC = ":".join(_MAC)
  52. return _MAC
  53. def convert_bin(d):
  54. return bin(d)[2:].rjust(8,"0")
  55. def convert_ip(d):
  56. IP="[0,0,0,0]"
  57. _ip = []
  58. try:
  59. _ip.append( d[0] )
  60. _ip.append( d[1] )
  61. _ip.append( d[2] )
  62. _ip.append( d[3] )
  63. IP = str(_ip)
  64. except:pass
  65. return IP
  66. def convert_to_hex(x,d):
  67. out = b""
  68. try:
  69. a = struct.unpack(x, d)[0]
  70. #out = hex(a)
  71. out = "{0:#0{1}x}".format(a,6)
  72. except:
  73. pass
  74. return out
  75. mc = None
  76. def connect_memcache():
  77. global mc
  78. try:
  79. import memcache
  80. mc = memcache.Client(['127.0.0.1:11211'], debug=0)
  81. clean_mc_artpoll()
  82. return 1
  83. except Exception as e:
  84. cprint("Err connect_memcache",e,color="red")
  85. return 0
  86. #thread.start_new_thread(connect_memcache, () )
  87. connect_memcache()
  88. from datetime import datetime
  89. def clean_mc_artpoll():
  90. if mc:
  91. INDEX="index-artpoll"
  92. mc.set(INDEX ,{})
  93. clean_mc_artpoll()
  94. def update_mc_artpoll_index(key,val=""):
  95. try:
  96. INDEX="index-artpoll"
  97. _index = mc.get(INDEX)
  98. #print("A",_index)
  99. if type(_index) is type(None):
  100. _index = {}
  101. #print("A",_index)
  102. #now = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
  103. now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  104. if key not in _index:
  105. _index[key] = [0,""]
  106. _index[key][0] += 1
  107. _index[key][1] = now #val
  108. mc.set(INDEX ,_index)
  109. except Exception as e:
  110. cprint(sys._getframe().f_code.co_name,opcode,color="red")
  111. cprint(" memcach exception",e,color="red")
  112. def ArtPollRawStore(data,addr):
  113. opcode=artnet_get_opcode(data)
  114. cprint(" ",sys._getframe().f_code.co_name,opcode,color="green")
  115. if "ArtPoll" in opcode or "ArtPollReplay" in opcode:
  116. #print("PKG3",addr, opcode,len(data))
  117. try:
  118. k = "{}:{}".format(addr[0],opcode[0])
  119. x=mc.set(k, data)
  120. if not x:
  121. cprint(" ArtPollRawStore memcache.not Connected mc.set",k,x,color="red")
  122. connect_memcache()
  123. update_mc_artpoll_index(k,val="")
  124. except Exception as e:
  125. cprint(" ArtPollRawStore err:",e,color="red")
  126. def artnet_get_opcode(head):
  127. #print([head]) #[9:10])
  128. opcode=0x0000
  129. name ="unkown"
  130. try:
  131. opcode=hex(struct.unpack('<h', head[8:10])[0])
  132. except:
  133. print("opcode error",[head])
  134. if opcode == '0x5000':
  135. name = "ArtDMX"
  136. elif opcode == '0x2000':
  137. name = "ArtPoll"
  138. elif opcode == '0x2100':
  139. name = "ArtPollReplay"
  140. return (name,opcode)
  141. def ArtNet_decode_pollreplay(data):
  142. debug = 0
  143. node = {}
  144. if len(data) < 10: #min opcode
  145. return node
  146. opcode=convert_to_hex("<h",data[8:10])
  147. if opcode != '0x2100': #OpPollReplay
  148. return node
  149. if len(data) < 207: #Mal
  150. return node
  151. #print(data[174:174+4])
  152. #print("===================================================================-")
  153. #print("decode",data[:13])
  154. # UDP PACKAGE VALUE:INDEX:RAGE
  155. CONF = {}
  156. CONF["IP"] = [10,14+1]
  157. CONF["port"] = [14,15+1]
  158. CONF["version"] = [16,17+1]
  159. CONF["NetSwitch"] = [18]
  160. CONF["SubSwitch"] = [19]
  161. CONF["oem"] = [20,21+1]
  162. CONF["ubea"] = [22]
  163. CONF["status"] = [23]
  164. CONF["esta"] = [24,25+1]
  165. CONF["sname"] = [26,26+17]
  166. CONF["lname"] = [44,44+43]
  167. CONF["NodeReport"] = [108,108+20]
  168. CONF["NumPort"] = [173]
  169. CONF["PortTypes"] = [174,174+4]
  170. CONF["GoodInput"] = [178,178+4]
  171. CONF["GoodOutput"] = [182,182+4]
  172. CONF["SwIn"] = [186,186+4]
  173. CONF["SwOut"] = [190,190+4]
  174. #CONF["MSG"] = [108,108+40]
  175. CONF["MAC"] = [201,201+6]
  176. cleanup = ["sname","lname","MSG","NodeReport"]
  177. for k,v in CONF.items():
  178. val = b'undefined'
  179. if len(v) == 2:
  180. val = data[v[0]:v[1]]
  181. if k in cleanup:
  182. val = val.strip(b"\x00")
  183. val = val.decode(errors="ignore")
  184. if len(v) == 1:
  185. val = data[v[0]]
  186. node[k] = val
  187. # ================================
  188. node["MAC"] = convert_mac(node["MAC"])
  189. node["IP"] = convert_ip(node["IP"])
  190. node["status"] = convert_bin(node["status"])
  191. node["opcode"] = opcode
  192. unpack = {"port":b"<H"}
  193. for k,v in node.items():
  194. if k in unpack:
  195. up = unpack[k]
  196. #print(k,v,up)
  197. node[k] = struct.unpack(up,v)[0]
  198. to_hex = {"version":'>H',"oem":'>H',"esta":"<H"}
  199. for k,u in to_hex.items():
  200. if k in node:
  201. v=node[k]
  202. node[k] = convert_to_hex(u,v)
  203. #for k,v in node.items():
  204. # if type(node[k]) is bytes:
  205. # node[k] = v.decode(errors="ignore")
  206. return node
  207. def test():
  208. UDP_ArtPollReplay = b'Art-Net\x00\x00!\x02\x00\x00T6\x19\x03P\x00\x00\x11\x10\x00\x00RUAADN-01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00AVR-ArtNet DMX NODE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Node is ready\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\x08\x00\x00\x00\x82\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb3\xd5\xfa\xff\xfa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  209. NODE_OLD = {'IP': '[2, 0, 0, 84]', 'port': (6454,), 'version': '\x03P', 'NetSwitch': 0, 'SubSwitch': 0, 'oem': '\x11\x10', 'ubea': 0, 'status': 0, 'esta': 'RU', 'sname': 'AADN-01', 'lname': 'AVR-ArtNet DMX NODE', 'NumPort': 1, 'PortTypes': '\x00\x00\x00', 'GoodInput': '\x08\x00\x00\x00', 'GoodOutput': '\x00\x00\x00', 'SwIn': '\x07\x00\x00\x00', 'SwOut': '\x00\x00\x00\x00', 'MSG': 'Node is ready', 'MAC': '70:b3:d5:fa:ff:fa'}
  210. NODE = {'IP': '[2, 0, 0, 84]', 'port': 6454, 'version': '0x0350', 'NetSwitch': 0, 'SubSwitch': 0, 'oem': '0x1110', 'ubea': 0, 'status': '00000000', 'esta': '0x5552', 'sname': 'AADN-01', 'lname': 'AVR-ArtNet DMX NODE', 'NodeReport': 'Node is ready', 'NumPort': 1, 'PortTypes': b'\x80\x00\x00\x00', 'GoodInput': b'\x08\x00\x00\x00', 'GoodOutput': b'\x82\x00\x00\x00', 'SwIn': b'\x07\x00\x00\x00', 'SwOut': b'\x00\x00\x00\x00', 'MAC': '70:b3:d5:fa:ff:fa', 'opcode': '0x2100'}
  211. node = ArtNet_decode_pollreplay(UDP_ArtPollReplay)
  212. k_miss =[]
  213. if NODE != node:
  214. for k,v in node.items():
  215. if k in NODE:
  216. print(v==NODE[k],"- diff -",k,v, NODE[k])
  217. else:
  218. k_miss.append(k)
  219. print("MISSING KEY:",k_miss)
  220. print(node)
  221. print(NODE)
  222. assert NODE == node
  223. def os_get_MAC(_filter=["vmbr0","br0"]):
  224. print(sys._getframe().f_code.co_name)
  225. cmd = "ip -j -o l l"
  226. r=os.popen(cmd)
  227. out="fa:00:00:00:00:00"
  228. out={}
  229. if not r:
  230. return out
  231. try:
  232. txt = r.read()
  233. data = json.loads(txt)
  234. for i in data:
  235. #print(i)
  236. if "ifname" not in i:
  237. continue
  238. #if i["ifname"] in _filter:
  239. if 1:
  240. dev = "none"
  241. if "ifname" in i:
  242. dev = i["ifname"]
  243. #if "." in dev:
  244. # continue
  245. if dev not in out:
  246. out[dev] = []
  247. if "address" in i:
  248. out[dev].append( i["address"])
  249. except Exception as e:
  250. print(e,e.args[0])
  251. return out
  252. def os_list_routing():
  253. print(sys._getframe().f_code.co_name)
  254. cmd="ip -j -o r l"
  255. r=os.popen(cmd)
  256. out={}
  257. if not r:
  258. return ips
  259. txt=r.read()
  260. jdata = json.loads(txt)
  261. for data in jdata:
  262. #print(data)
  263. dev = "none"
  264. if "dev" in data:
  265. dev = data["dev"]
  266. if dev not in out:
  267. out[dev] = []
  268. if "dst" in data:
  269. out[dev].append(data["dst"])
  270. return out
  271. def os_list_ip():
  272. print(sys._getframe().f_code.co_name)
  273. ips = {}
  274. cmd="ip -o -j -4 a l "
  275. r=os.popen(cmd)
  276. if not r:
  277. return ips
  278. txt=r.read()
  279. jdata = json.loads(txt)
  280. for data in jdata:
  281. #print(data)
  282. if "addr_info" in data:
  283. infos = data["addr_info"]
  284. for info in infos:
  285. dev = "None"
  286. if "dev" in info:
  287. dev = info["dev"]
  288. if "local" in info:
  289. ip = info["local"]
  290. if "prefixlen" in info:
  291. ip += "/"+str(info["prefixlen"])
  292. #if "." in dev:
  293. # continue
  294. if dev not in ips:
  295. ips[dev] = []
  296. ips[dev].append(ip)
  297. #print(" ",[dev,ip])
  298. return ips
  299. #ips = os_list_ip() #example
  300. #get_mask(ips)
  301. def ArtAddress(ip="192.168.0.99" ,ShortName="ShortName", LongName="LongName",Port="",Universes=0,raw=0):
  302. sock = UDP_Socket()
  303. node_nr = 1
  304. #send port
  305. port = 7600
  306. port = 6454
  307. print( ip)
  308. data = [] # [struct.pack('<B', 0)]*150
  309. header = []
  310. # Name, 7byte + 0x00
  311. header.append(b"Art-Net\x00")
  312. # OpCode ArtDMX -> 0x6000, Low Byte first
  313. header.append(struct.pack('<H', 0x6000))
  314. # Protocol Version 14, High Byte first
  315. header.append(struct.pack('>H', 14))
  316. data = header[:]
  317. # NetSwitch
  318. data.append(struct.pack('<B',128)) # no change 0x7f
  319. data.append(struct.pack('<B', 0)) # filler
  320. #Short Name
  321. sname = ShortName[:17]
  322. sname = sname.ljust(18,"\x00")
  323. data.append( sname )
  324. lname = LongName[:63]
  325. lname = lname.ljust(64,"\x00")
  326. #lname = lname[:-2]+"X\x00"
  327. data.append( lname )
  328. print( "len sname:lname",len(sname),len(lname))
  329. #SwIn 4; Port-Adress
  330. # univers 0-f == \x80 - \x8f
  331. i = 4
  332. i=int(Universes)+1 #random.randint(0,99)
  333. data.append(struct.pack('<B', 127+i))
  334. data.append(struct.pack('<B', 127+i))
  335. data.append(struct.pack('<B', 127+i))
  336. data.append(struct.pack('<B', 127+i))
  337. #SwOut 4; Port-Adress
  338. data.append(struct.pack('<B', 127+i))
  339. data.append(struct.pack('<B', 127+i))
  340. data.append(struct.pack('<B', 127+i))
  341. data.append(struct.pack('<B', 127+i))
  342. #SubSwitch comination with Swin[] SwOut[]
  343. data.append(struct.pack('<B', 0)) # SubSwitch Write 128
  344. data.append(struct.pack('<B', 255))
  345. data.append(struct.pack('<B', 0))
  346. data.append(struct.pack('<B', 0))
  347. #data.append("\xf4")
  348. #print( ["ArtAdress SEND:",data,(ip,port)] )
  349. data2 = b""
  350. for d in data:
  351. #print(d,type(d))
  352. if type(d) is str:
  353. data2+=bytes(d,"utf-8")
  354. elif type(d) is bytes:
  355. data2+=d
  356. else:
  357. data2+=bytes(str(d),"ascii")
  358. print(data2)
  359. if raw:
  360. return data2,(ip,port)
  361. sock.sendto(data2 ,(ip,port))
  362. def set_ip4(cur_ip=(2,0,0,91),new_ip=(2,0,0,201),new_netmask=(255,0,0,0)):
  363. sock = UDP_Socket()
  364. #send ip
  365. port = 7600
  366. #print(ip)
  367. data = []
  368. #New ip
  369. #_ip = [192, 168, 2, 91]
  370. _ip = [ 2, 0, 0, 181] # CLASS C NET
  371. _ip = [ 2, 0, 0, 101] # CLASS C NET
  372. #_ip = [192, 168, 0, 91]
  373. _ip = new_ip
  374. print("NEW NODE _ip:", _ip)
  375. data.append(struct.pack('<B', _ip[0]))
  376. data.append(struct.pack('<B', _ip[1]))
  377. data.append(struct.pack('<B', _ip[2]))
  378. data.append(struct.pack('<B', _ip[3]))
  379. #_ip = [255, 255, 255, 255] # cange all nodes in Network to the same _ip ! DANGER !
  380. #_ip = [002, 000, 000, 255] # cange all nodes in subnet to the same _ip ! DANGER !
  381. _ip = [ 2, 0, 0, 199] # CLASS A NET
  382. _ip = [192, 168, 0, 91]
  383. #_ip = [ 2, 0, 0, 191] # CLASS C NET
  384. _ip = cur_ip
  385. print("OLD NODE _ip:", _ip)
  386. #OLD _ip , Target Node to change
  387. data.append(struct.pack('<B', _ip[0]))
  388. data.append(struct.pack('<B', _ip[1]))
  389. data.append(struct.pack('<B', _ip[2]))
  390. data.append(struct.pack('<B', _ip[3]))
  391. ip = ".".join(str(x) for x in _ip)
  392. #print("send to ip:", ip)
  393. # NETMASK
  394. MASK = []
  395. netmask = [255, 255, 255 , 0] #fast CLASS C funktioniert
  396. #netmask = [255, 0, 0 , 0] #CLASS C funkioniert nicht
  397. netmask = new_netmask
  398. print("NEW NODE net:",netmask)
  399. MASK.append(struct.pack('<B', netmask[0]))
  400. MASK.append(struct.pack('<B', netmask[1]))
  401. MASK.append(struct.pack('<B', netmask[2]))
  402. MASK.append(struct.pack('<B', netmask[3]))
  403. data += MASK
  404. data += [struct.pack('<B', 255)]*11
  405. print("------------------------------")
  406. data = b'CMD IP '+ b"".join(data)
  407. print("SENDING TO ",(ip,port))
  408. print([data]) #, cur_ip=(2,0,0,91))
  409. #sock.sendto(data ,(ip,port))
  410. sock.sendto(data ,(ip,port))
  411. def send_cmd(ip=(2,0,0,91),cmd=""):
  412. sock = UDP_Socket()
  413. node_nr = 1
  414. port = 7600
  415. print(ip)
  416. data = []
  417. _ip = [ 2, 0, 0, 91] # CLASS C NET
  418. print("NEW NODE _ip:", _ip)
  419. data.append(struct.pack('<B', _ip[0]))
  420. data.append(struct.pack('<B', _ip[1]))
  421. data.append(struct.pack('<B', _ip[2]))
  422. data.append(struct.pack('<B', _ip[3]))
  423. #_ip = [255, 255, 255, 255] # cange all nodes in Network to the same _ip ! DANGER !
  424. #_ip = [002, 000, 000, 255] # cange all nodes in subnet to the same _ip ! DANGER !
  425. _ip = [ 2, 0, 0, 199] # CLASS A NET
  426. _ip = [ 2, 0, 0, 91] # CLASS A NET
  427. #_ip = [192, 168, 0, 91]
  428. _ip = [ 2, 0, 0, 255] # CLASS C NET
  429. #_ip = [ 2, 255, 255, 255] # CLASS C NET
  430. print("OLD NODE _ip:", _ip)
  431. #OLD _ip , Target Node to change
  432. data.append(struct.pack('<B', _ip[0]))
  433. data.append(struct.pack('<B', _ip[1]))
  434. data.append(struct.pack('<B', _ip[2]))
  435. data.append(struct.pack('<B', _ip[3]))
  436. ip = ".".join(str(x) for x in ip)
  437. print("send to ip:", ip)
  438. # NETMASK
  439. MASK = []
  440. netmask = [255, 255, 255 , 0] #fast CLASS C funktioniert
  441. netmask = [255, 0, 0 , 0] #CLASS C funkioniert nicht
  442. print("NEW NODE net:",netmask)
  443. MASK.append(struct.pack('<B', netmask[0]))
  444. MASK.append(struct.pack('<B', netmask[1]))
  445. MASK.append(struct.pack('<B', netmask[2]))
  446. MASK.append(struct.pack('<B', netmask[3]))
  447. data += MASK
  448. data += [struct.pack('<B', 255)]*11
  449. print("------------------------------")
  450. data = 'CMD '+cmd+' '+ "".join(data)
  451. print("SENDING TO ",(ip,port))
  452. print([data] )
  453. #sock.sendto(data ,(ip,port))
  454. sock.sendto(data ,(ip,port))
  455. def pack_ip(_ip):
  456. data = [b"\x00",b"\x00", b"\x00", b"\x00"]
  457. if "." in _ip:
  458. _ip = _ip.split(".")
  459. if _ip:
  460. data[0] = struct.pack('<B', int(_ip[0]))
  461. data[1] = struct.pack('<B', int(_ip[1]))
  462. data[2] = struct.pack('<B', int(_ip[2]))
  463. data[3] = struct.pack('<B', int(_ip[3]))
  464. return data
  465. def send_node_cmd(ip="",ip2="",cmd=""):
  466. sock = UDP_Socket()
  467. print()
  468. port = 7600
  469. data = []
  470. print("send_node_cmd",ip,ip2,cmd,port)
  471. data = pack_ip(ip[:])
  472. print("ip",ip,ip2)
  473. if len(ip2) == 4:
  474. ip = ip2
  475. if len(ip) == 4:
  476. ip = ".".join(map(str,ip))
  477. print("send to ip:", ip)
  478. data2=""
  479. if not cmd:
  480. data2 = 'CMD GT'
  481. data2 = 'CMD ST'
  482. data2 = 'DMX OUT STORE'
  483. data2 = 'CMD DMX=IN '
  484. data2 = 'CMD DMX=OUT '
  485. data2 = 'CMD DMX=PIN '
  486. if type(cmd) == bytes:
  487. data2 = cmd
  488. else:
  489. data2 = bytes(str(cmd),"ascii",errors="ignore")
  490. print([data2],type(data2) )
  491. data2 = data2.ljust(20,b" ") + b"".join(data)
  492. print("SENDING COMMAND TO ",[data2],(ip,port))
  493. sock.sendto(data2 ,(ip,port))
  494. def get_mask(IP):
  495. print(sys._getframe().f_code.co_name)
  496. import ipaddress
  497. #mask=ipaddress.IPv4Network(IP+'/8',False)
  498. #print(mask,mask.netmask)
  499. #mask=ipaddress.IPv4Network(IP+'/24',False)
  500. mask=ipaddress.IPv4Network(IP,False)
  501. #print(IP,mask.netmask)
  502. return mask.netmask
  503. def ArtPollReply(sock=None):
  504. print(sys._getframe().f_code.co_name)
  505. if not sock:
  506. sock=UDP_Socket()
  507. port = 6454
  508. content = []
  509. content2=[]
  510. for c in content:
  511. if type(c) is not bytes:
  512. c= bytes(c,"ascii")
  513. content2.append(c)
  514. content = b''.join(content2)
  515. fill = 240-len(content)-1
  516. print()
  517. if fill > 0:
  518. content = content + b"\x00"*fill
  519. def create_ip(IP,content):
  520. #CONF["IP"] = [10,14+1]
  521. x=[]
  522. j=10
  523. for i in IP.split("."):
  524. i = 33
  525. _ip = struct.pack("B",int(i))
  526. # content = content[:10+j]+ _ip + content[10+j:]
  527. content = inject(j,_ip,content)
  528. j+=1
  529. x.append([_ip,i])
  530. print(IP,x)
  531. def patch(content,index,patch):
  532. _patch = patch[:]
  533. if type(_patch) != bytes:
  534. _patch=bytes(_patch,"ascii")
  535. content[index:index+len(_patch)] = _patch
  536. def pad(val,count,fill="\x00"):
  537. return val.ljust(count,fill)[:count]
  538. def ip_to_byte(IP):
  539. out=[]
  540. for i in IP.split("."):
  541. out.append( int(i) )
  542. return bytes(out)
  543. print()
  544. #IP="2.0.0.255"
  545. #create_ip(IP,content)
  546. #sock.sendto(content, (IP, port))
  547. # =======================================
  548. content = [0]*(282-42) # new empty PKG bytes([0,0,0,..])
  549. patch(content,0, b"Art-Net\x00")
  550. patch(content,8, b"\x00\x21") # revers 0x2100 protocol
  551. hostname=os.popen("hostname").read().strip()
  552. #hostname+="0123456789012345678901234567890123456789012345678901234567890"
  553. sname=pad(hostname,18) # Short Name, len == 30
  554. patch(content,26,sname)
  555. lname=pad("LibreLight "+hostname,64) # Long Name, len == 64
  556. patch(content,26+18,lname)
  557. Report="LibreLight is ready CPU:40%"
  558. #Report+="12345678901234567890123456789012345123456789012345678901234567890"
  559. Report=pad(Report,64)
  560. patch(content,26+28+54,Report)
  561. ips=os_list_ip()
  562. mac= os_get_MAC()
  563. if "vmbr0" in mac:
  564. mac = mac["vmbr0"][0]
  565. print()
  566. print([mac])
  567. print()
  568. mac=mac.replace(":","")
  569. print([mac])
  570. if len(mac) == 12:
  571. mac=bytes.fromhex(mac)
  572. #content[201:] = mac
  573. patch(content,201,mac)
  574. #print([mac])
  575. print("send" ,[content])
  576. for IP in ["192.168.2.255","2.0.0.255","10.10.10.255"]:
  577. content2 = content[:]
  578. _IP = ip_to_byte(IP)
  579. patch(content2,10,_IP)
  580. content2 = bytes(content2)
  581. sock.sendto(content2, (IP, port))
  582. print("send" ,[content])
  583. def ArtNet_Server(verbose=0):
  584. print("start main()")
  585. sock = UDP_Socket(bind=True,ip='',port=6454)
  586. print(" -- loop --")
  587. while sock:
  588. data, addr = sock.recvfrom(300)
  589. cprint(" <- ArtNet_Server rcv:",[addr],color="cyan")
  590. ArtPollRawStore(data,addr)
  591. opcode=""
  592. if len(data) >= 10:
  593. opcode=convert_to_hex("<h",data[8:10])
  594. if opcode != '0x2100': #OpPollReplay
  595. continue
  596. print(" <-",addr,len(data),opcode)
  597. if verbose:
  598. nodes = ArtNet_decode_pollreplay(data)
  599. for k,v in nodes.items():
  600. print("-",[k,v])
  601. print("end main()")
  602. def print_help():
  603. print("help -h --help ")
  604. print(" --main")
  605. print(" --ArtPoll")
  606. print(" --ArtPollReplay")
  607. if __name__ == "__main__":
  608. test()
  609. if "-h" in sys.argv or "--help" in sys.argv:
  610. print_help()
  611. elif "--ArtPoll" in sys.argv:
  612. ArtPoll()
  613. elif "--ArtPollReplay" in sys.argv:
  614. ArtPollReply()
  615. elif "-MAC" in sys.argv:
  616. mac= os_get_MAC()
  617. for k,v in mac.items():
  618. print("-",k,v)
  619. print()
  620. for k,v in os_list_ip().items():
  621. print("-",k,v)
  622. print()
  623. for k,v in os_list_routing().items():
  624. print("-",k,v)
  625. print()
  626. print( get_mask("192.168.2.2/24"))
  627. print( get_mask("192.168.2.2/25"))
  628. print( get_mask("192.168.2.2/8"))
  629. elif "--main" in sys.argv:
  630. def loop():
  631. while 1:
  632. ArtPoll()
  633. time.sleep(5)
  634. thread.start_new_thread(loop,())
  635. ArtNet_Server(verbose=1)
  636. else:
  637. print_help()