import json, os, socket, ssl, sys, time from urllib.request import Request, urlopen from urllib.error import HTTPError PROTO='jarvis.skill.invoke.v1' def fail(c,m): return {'protocol':PROTO,'success':False,'error':{'code':c,'message':m}} def ok(d,m='OK',mut=False): return {'protocol':PROTO,'success':True,'data':d,'message':m,'mutated':mut} def main(inv): a=inv.get('action'); x=inv.get('input') or {} if a=='tcp_check': t=time.perf_counter(); reachable=True try: with socket.create_connection((x['host'],int(x['port'])),timeout=float(x.get('timeout_seconds',3))): pass except OSError: reachable=False ms=(time.perf_counter()-t)*1000; return ok({'reachable':reachable,'latency_ms':round(ms,2)},'TCP-Prüfung abgeschlossen.') if a=='http_check': t=time.perf_counter(); status=0; reachable=False; verify=bool(x.get('verify_tls',True)); ctx=None if x['url'].startswith('https://') and not verify: ctx=ssl._create_unverified_context() try: with urlopen(Request(x['url'],headers={'User-Agent':'JARVIS-Skill/1'}),timeout=float(x.get('timeout_seconds',5)),context=ctx) as r: status=int(r.status); reachable=True except HTTPError as e: status=int(e.code); reachable=True except Exception: pass ms=(time.perf_counter()-t)*1000; return ok({'reachable':reachable,'status':status,'latency_ms':round(ms,2)},'HTTP-Prüfung abgeschlossen.') if a=='dns_lookup': vals=sorted({i[4][0] for i in socket.getaddrinfo(x['host'],None)}); return ok({'addresses':vals,'count':len(vals)},'DNS aufgelöst.') if a=='wake_on_lan': mac=''.join(c for c in x['mac'] if c.isalnum()) if len(mac)!=12: return fail('INVALID_MAC','MAC-Adresse ungültig') packet=b'\xff'*6+bytes.fromhex(mac)*16; broad=x.get('broadcast') or os.getenv('WOL_BROADCAST','255.255.255.255'); port=int(x.get('port') or os.getenv('WOL_PORT','9')) s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1); s.sendto(packet,(broad,port)); s.close() return ok({'sent':True,'broadcast':broad,'port':port},'Wake-on-LAN gesendet.',True) return fail('UNKNOWN_ACTION',f'Unbekannte Aktion: {a}') try: res=main(json.load(sys.stdin)) except Exception as e: res=fail('NETWORK_TOOL_ERROR',str(e)) json.dump(res,sys.stdout,ensure_ascii=False)