sisniff 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. #!/usr/bin/env python3
  2. # (c) 2017-2025 by Siegrist(SystemLoesungen) <PSS@ZweierNet.ch>
  3. #
  4. # All Rights reserved.
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License as
  7. # published by the Free Software Foundation.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. from scapy.all import *
  15. #import traceback
  16. import pwd
  17. import os
  18. import re
  19. import glob
  20. import sys
  21. import string
  22. import fcntl
  23. import struct
  24. import argparse
  25. if sys.version_info.major == 3:
  26. try:
  27. #from dnslib.dns import DNSRecord,DNSHeader,DNSQuestion,DNSError,QTYPE,EDNS0
  28. from dnslib import DNSRecord
  29. have_DNSLIB = True
  30. except:
  31. have_DNSLIB = False
  32. #print("Missing 'python3-dnslib': DNS-Payload not available.")
  33. #if sys.version_info.major == 2:
  34. # import commands as subprocess
  35. #elif sys.version_info.major == 3:
  36. # import subprocess
  37. def _to_str(inp):
  38. if sys.version_info.major == 2:
  39. return inp
  40. else:
  41. return "".join( chr(x) for x in inp)
  42. VERSION = "1.7.0"
  43. PROC_TCP4 = "/proc/net/tcp"
  44. PROC_UDP4 = "/proc/net/udp"
  45. PROC_ICMP4 = "/proc/net/icmp"
  46. PROC_TCP6 = "/proc/net/tcp6"
  47. PROC_UDP6 = "/proc/net/udp6"
  48. PROC_PACKET = "/proc/net/packet"
  49. # Services
  50. TSERV = dict((TCP_SERVICES[k], k) for k in TCP_SERVICES.keys())
  51. USERV = dict((UDP_SERVICES[k], k) for k in UDP_SERVICES.keys())
  52. # IP Protocol Numbers (dec)
  53. IPPROTO_ICMP = 1
  54. IPPROTO_TCP = 6
  55. IPROTOP_IGP = 9
  56. IPPROTO_UDP = 17
  57. nostate = set(['04','05','06''07','08','09','0C','0D'])
  58. tcp_payload_hdrs = ['GET|POST|HTTP|HEAD|PUT|PATCH|DELETE|TRACE|OPTIONS|CONNECT']
  59. RCODE={0:'', 1:'FORMERR ', 2:'SERVFAIL ', 3:'NXDomain* ',4:'NOTIMP ', 5:'REFUSED ', 6:'YXDOMAIN ', 7:'YXRRSET ',8:'NXRRSET ', 9:'NOTAUTH ', 10:'NOTZONE '}
  60. DNS_QTYPE={1:'A', 2:'NS', 5:'CNAME', 6:'SOA', 10:'NULL', 12:'PTR', 13:'HINFO',
  61. 15:'MX', 16:'TXT', 17:'RP', 18:'AFSDB', 24:'SIG', 25:'KEY',
  62. 28:'AAAA', 29:'LOC', 33:'SRV', 35:'NAPTR', 36:'KX',
  63. 37:'CERT', 38:'A6', 39:'DNAME', 41:'OPT', 42:'APL',
  64. 43:'DS', 44:'SSHFP', 45:'IPSECKEY', 46:'RRSIG', 47:'NSEC',
  65. 48:'DNSKEY', 49:'DHCID', 50:'NSEC3', 51:'NSEC3PARAM',
  66. 52:'TLSA', 53:'HIP', 55:'HIP', 59:'CDS', 60:'CDNSKEY',
  67. 61:'OPENPGPKEY', 62:'CSYNC', 63:'ZONEMD', 64:'SVCB',
  68. 65:'HTTPS', 99:'SPF', 108:'EUI48', 109:'EUI64', 249:'TKEY',
  69. 250:'TSIG', 251:'IXFR', 252:'AXFR', 255:'ANY', 256:'URI',
  70. 257:'CAA', 32768:'TA', 32769:'DLV'}
  71. numeric = False
  72. payloadH = False
  73. payloadHl = False
  74. payloadDNS = False
  75. fillter = ""
  76. def get_conn_info(proto,hosts,ports,ipvers):
  77. ''' returns: pid, exe, uid '''
  78. uid = 0
  79. line_array = _proc4load(proto,hosts,ports,ipvers)
  80. if line_array == 0:
  81. return ['?','?','?']
  82. '''
  83. try:
  84. uid = pwd.getpwuid(int(line_array[7]))[0] # Get user from UID.
  85. except:
  86. uid = line_array[7]
  87. '''
  88. inode = str(line_array[9])
  89. if inode == "0":
  90. return ['.','.','.']
  91. pid = _get_pid_of_inode(inode) # try get a pid
  92. if pid == "NoPid":
  93. #print(">>>>>>>>>>>NoPID:" + str(hosts) +" "+ str(ports) + "//" + str(line_array))
  94. return ['-', '-', uid]
  95. try: # try read the process name.
  96. exe = os.readlink('/proc/'+pid+'/exe').split('/')[-1]
  97. except:
  98. exe = None
  99. #print(str(lhost) +" "+ str(lport) +" "+ inode +" "+ pid)
  100. return [pid, exe, uid]
  101. def _proc4load(proto,hosts,ports,ipvers):
  102. ''' Read the table of tcp/udp connections
  103. tcp/udp: "sl, local_address, rem_address, st, tx_queue rx_queue, tr tm->when, retrnsmt, uid , timeout, inode ,..."
  104. ---- TCP states from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/net/tcp_states.h?id=HEAD
  105. enum {
  106. TCP_ESTABLISHED = 1,
  107. TCP_SYN_SENT,
  108. TCP_SYN_RECV,
  109. TCP_FIN_WAIT1,
  110. TCP_FIN_WAIT2,
  111. TCP_TIME_WAIT,
  112. TCP_CLOSE,
  113. TCP_CLOSE_WAIT,
  114. TCP_LAST_ACK,
  115. TCP_LISTEN,
  116. TCP_CLOSING, /* Now a valid state */
  117. TCP_NEW_SYN_RECV,
  118. TCP_MAX_STATES /* Leave at the end! */
  119. };
  120. ----------
  121. '''
  122. #xhosts = _ip_hexrev(hosts)
  123. xports = _dec2hex(ports)
  124. if proto == IPPROTO_UDP:
  125. try:
  126. procv = PROC_UDP4
  127. if ipvers == 6:
  128. procv = PROC_UDP6
  129. with open(procv,'r') as f:
  130. next(f)
  131. for line in f:
  132. line_arrayu = _remove_empty(line.split(' '))
  133. l_xhost,l_xport = line_arrayu[1].split(':')
  134. if l_xhost not in xMYADDRS:
  135. continue
  136. if l_xport == xports:
  137. return line_arrayu
  138. return 0
  139. except:
  140. print("open proc_udp4 error")
  141. return 0
  142. elif proto == IPPROTO_TCP:
  143. try:
  144. procv = PROC_TCP4
  145. if ipvers == 6:
  146. procv = PROC_TCP6
  147. with open(procv,'r') as f:
  148. next(f)
  149. for line in f:
  150. line_arrayt = _remove_empty(line.split(' '))
  151. if line_arrayt[3] in nostate: # not some TCP state
  152. continue
  153. l_xhost,l_xport = line_arrayt[1].split(':')
  154. if l_xhost not in xMYADDRS:
  155. continue
  156. if l_xport == xports:
  157. return line_arrayt
  158. return 0
  159. except:
  160. print("open proc_tcp error")
  161. return 0
  162. elif proto == IPPROTO_ICMP:
  163. try:
  164. procv = PROC_ICMP4
  165. if ipvers == 6:
  166. procv = PROC_ICMP6
  167. with open(procv,'r') as f:
  168. next(f)
  169. for line in f:
  170. line_arrayi = _remove_empty(line.split(' '))
  171. l_xhost,l_xport = line_arrayi[1].split(':')
  172. if l_xhost not in xMYADDRS:
  173. continue
  174. if l_xport == xports:
  175. return line_arrayi
  176. return 0
  177. except:
  178. print("open proc_icmp4 error")
  179. return 0
  180. return 0
  181. def _convert_ipv4_port(array):
  182. host,port = array.split(':')
  183. return _ip(host),_hex2dec(port)
  184. def _hex2dec(s):
  185. return str(int(s,16))
  186. def _dec2hex(p):
  187. return hex(int(p)).split('x')[-1].upper()
  188. def _ip(s):
  189. ip = [(_hex2dec(s[6:8])),(_hex2dec(s[4:6])),(_hex2dec(s[2:4])),(_hex2dec(s[0:2]))]
  190. return '.'.join(ip)
  191. def _ip6(s):
  192. ip = [s[6:8],s[4:6],s[2:4],s[0:2],s[14:16],s[12:14],s[10:12],s[8:10],s[22:24],s[20:22],s[18:20],s[16:18],s[30:32],s[28:30],s[26:28],s[24:26]]
  193. return ':'.join(ip)
  194. def _ip_hexrev(ip):
  195. return ''.join([hex(int(x)+256)[3:] for x in ip.split('.')][::-1]).upper()
  196. # IPv6 /proc/net/tcp6 format from expanded ip-address
  197. def _to_v6_proc(s):
  198. s = s.replace(":", "")
  199. ip = [s[6:8],s[4:6],s[2:4],s[0:2],s[14:16],s[12:14],s[10:12],s[8:10],s[22:24],s[20:22],s[18:20],s[16:18],s[30:32],s[28:30],s[26:28],s[24:26]]
  200. return ''.join(ip).upper()
  201. def expand_v6(ip):
  202. ipa = ip.split(':') # liste
  203. if '' in ipa:
  204. if ipa.count('') > 1: # korr ::1 or :::
  205. for i in range(ipa.count('')-1):
  206. ipa.remove('')
  207. miss = 8 - len(ipa) +1
  208. for i in range(miss):
  209. ipa.insert(ipa.index('')+i, '0000')
  210. ipa.remove('')
  211. return ':'.join(["%04x" % x for x in [int(x, 16) for x in ipa]])
  212. else:
  213. return ':'.join(["%04x" % x for x in [int(x, 16) for x in ipa]])
  214. def _remove_empty(array):
  215. return [x for x in array if x != '']
  216. def _get_pid_of_inode(inode):
  217. s_term = '['+ inode +']'
  218. for item in glob.iglob('/proc/[0-9]*/fd/[0-9]*'):
  219. try:
  220. searchlnk = os.readlink(item)
  221. except:
  222. continue
  223. try:
  224. if s_term in searchlnk:
  225. return item.split('/')[2]
  226. except:
  227. pass
  228. return "NoPid"
  229. def _resolve_ip(host):
  230. """
  231. resolve ip und update dictionary res_cache {'ip': 'name'}.
  232. If resolution for a ip failed, 'name' is n_try ... 0.
  233. """
  234. try:
  235. hname = socket.gethostbyaddr(host)[0]
  236. res_cache[host] = str(hname)
  237. return str(hname)
  238. except:
  239. res_cache[host] = str(host)
  240. return str(host)
  241. def check_root():
  242. if os.getuid() == 0:
  243. return True
  244. else:
  245. return False
  246. ## Define our Custom Action function
  247. def doPackets(packet):
  248. program = "-"
  249. pid = "-"
  250. uid = "-"
  251. o_proto = ""
  252. o_dport = "none"
  253. o_sport = "none"
  254. flags = ""
  255. # only local addresses
  256. if packet[0][1].src in MYADDRS:
  257. conn_addr = packet[0][1].src
  258. if packet.haslayer(TCP) or packet.haslayer(UDP) or packet.haslayer(ICMP):
  259. try:
  260. conn_port = packet[0][2].sport
  261. except:
  262. conn_port = 99999
  263. o_dir = 1
  264. else:
  265. conn_addr = packet[0][1].dst
  266. if packet.haslayer(TCP) or packet.haslayer(UDP) or packet.haslayer(ICMP):
  267. try:
  268. conn_port = packet[0][2].dport
  269. except:
  270. conn_port = 99999
  271. o_dir = 0
  272. if packet.haslayer(TCP) or packet.haslayer(UDP) or packet.haslayer(ICMP): # grrr, no info in /proc/net/icmp so far. or packet.haslayer(ICMP):
  273. # logemol casch
  274. c_hash = conn_addr+'=:='+str(conn_port)
  275. if not any(x[0] == c_hash for x in conn_cache):
  276. # get the connection info from packet
  277. if packet[0][1].version == 4:
  278. spid,sexe,suid = get_conn_info(packet[0][1].proto, conn_addr, conn_port, packet[0][1].version)
  279. elif packet[0][1].version == 6:
  280. spid,sexe,suid = get_conn_info(packet[0][1].nh, conn_addr, conn_port, packet[0][1].version)
  281. if re.match("[0-9]+$", spid):
  282. program = sexe
  283. pid = spid
  284. uid = suid
  285. # update cache
  286. if len(conn_cache) >= cc_maxlen:
  287. conn_cache.pop(0)
  288. conn_cache.append([c_hash,program,pid])
  289. else:
  290. program = sexe
  291. pid = spid
  292. uid = suid
  293. else:
  294. # me honds fom casch
  295. indx = [x[0] for x in conn_cache].index(c_hash)
  296. program = conn_cache[indx][1]
  297. pid = conn_cache[indx][2]
  298. uid = 0
  299. # cache aktualisieren
  300. renew = conn_cache.pop(indx)
  301. conn_cache.append(renew)
  302. try:
  303. filter_prog
  304. except:
  305. pass
  306. else:
  307. if have_filter_progn:
  308. if have_filter_progn1 and re.search(filter_progn[1:-1], program):
  309. return
  310. elif have_filter_progn2 and re.search(filter_progn[1:]+'$', program):
  311. return
  312. elif have_filter_progn3 and re.match('^'+filter_progn[:-1], program):
  313. return
  314. elif have_filter_progn4 and re.match('^'+filter_progn+'$', program):
  315. return
  316. else:
  317. if have_filter_prog1 and not re.search(filter_prog[1:-1], program):
  318. return
  319. elif have_filter_prog2 and not re.search(filter_prog[1:]+'$', program):
  320. return
  321. elif have_filter_prog3 and not re.match('^'+filter_prog[:-1], program):
  322. return
  323. elif have_filter_prog4 and not re.match('^'+filter_prog+'$', program):
  324. return
  325. o_payload = ""
  326. if packet.haslayer(UDP):
  327. o_proto = "UDP"
  328. try:
  329. o_dport = "\033[1m"+USERV[packet[0][2].dport]+"\033[0m"
  330. except:
  331. o_dport = str(packet[0][2].dport)
  332. try:
  333. o_sport = "\033[1m"+USERV[packet[0][2].sport]+"\033[0m"
  334. except:
  335. o_sport = str(packet[0][2].sport)
  336. flags = ""
  337. #o_payload = _to_str(packet[0].sprintf('%10s,UDP.payload%'))
  338. if payloadDNS == True:
  339. if DNS in packet:
  340. ppd = packet[0][DNS]
  341. p_upld = DNSRecord.parse(bytes(packet[0][DNS]))
  342. if ppd.qdcount > 0 and ppd.qr == 0:
  343. o_payload = "DNS -> (" + str(ppd.id) + "): " + RCODE[ppd.rcode]
  344. o_payload += DNS_QTYPE[p_upld.q.qtype] + "? " + str(p_upld.q.qname)
  345. elif ppd.qdcount > 0 and ppd.qr == 1:
  346. o_payload = "DNS <- (" + str(ppd.id) + "): " + RCODE[ppd.rcode]
  347. rr_cnt = 0
  348. for rr in p_upld.rr:
  349. o_payload += f'{rr.rname} {DNS_QTYPE[rr.rtype]} {rr.rdata} | '
  350. rr_cnt += 1
  351. if rr_cnt > 0:
  352. o_payload = o_payload[:-3]
  353. else:
  354. o_payload = "DNS: " + RCODE[ppd.rcode] + str(p_upld)
  355. elif packet.haslayer(TCP):
  356. o_proto = "TCP"
  357. try:
  358. o_dport = "\033[1m"+TSERV[packet[0][2].dport]+"\033[0m"
  359. except:
  360. o_dport = str(packet[0][2].dport)
  361. try:
  362. o_sport = "\033[1m"+TSERV[packet[0][2].sport]+"\033[0m"
  363. except:
  364. o_sport = str(packet[0][2].sport)
  365. flags = packet[0].sprintf('%3s,TCP.flags%')
  366. if payloadH == True:
  367. if packet.haslayer(Raw):
  368. #tpld = packet[0].sprintf('%TCP.payload%')
  369. tpld = _to_str(packet[0][TCP].load)
  370. tpldhead = tpld[0:8]
  371. #print("tpld:" + tpldhead)
  372. if re.match(r'GET|POST|HTTP|HEAD|PUT|PATCH|DELETE|TRACE|OPTIONS|CONNECT.*', tpldhead):
  373. if payloadHl == True:
  374. o_payload = str(tpld)
  375. else:
  376. request_line, gaga = tpld.split('\r\n', 1)
  377. o_payload = str(request_line)
  378. #o_payload = tpld[0:20]
  379. if payloadDNS == True:
  380. if DNS in packet:
  381. ppd = packet[0][DNS]
  382. ppd2 = bytes(packet[0][DNS])[2:] # !!$??@! remove length field (2Byte) from DNS-Record for use with DNSRecord.parse() ??!!!!
  383. p_tpld = DNSRecord.parse(bytes(ppd2))
  384. if ppd.qdcount > 0 and ppd.qr == 0:
  385. o_payload = "DNS -> (" + str(ppd.id) + "): " + RCODE[ppd.rcode]
  386. o_payload += DNS_QTYPE[p_tpld.q.qtype] + "? " + str(p_tpld.q.qname)
  387. elif ppd.qdcount > 0 and ppd.qr == 1:
  388. o_payload = "DNS <- (" + str(ppd.id) + "): " + RCODE[ppd.rcode]
  389. rr_cnt = 0
  390. for rr in p_tpld.rr:
  391. o_payload += f'{rr.rname} {DNS_QTYPE[rr.rtype]} {rr.rdata} | '
  392. rr_cnt += 1
  393. if rr_cnt > 0:
  394. o_payload = o_payload[:-3]
  395. else:
  396. o_payload = "DNS??: " + RCODE[ppd.rcode] + str(p_tpld)
  397. elif packet.haslayer(ICMP):
  398. o_proto = "ICMP"
  399. if conn_port == 99999:
  400. o_dport = "-"
  401. o_sport = "-"
  402. else:
  403. try:
  404. o_dport = "\033[1m"+USERV[packet[0][2].sport]+"\033[0m"
  405. except:
  406. o_dport = str(packet[0][2].sport)
  407. try:
  408. o_sport = "\033[1m"+USERV[packet[0][2].dport]+"\033[0m"
  409. except:
  410. o_sport = str(packet[0][2].dport)
  411. flags = "["+packet[0].sprintf('%ICMP.type%') + "/" + packet[0].sprintf('%ICMP.code%')+"]"
  412. else:
  413. layerukn = packet[0][1].getlayer(1)
  414. if layerukn is None:
  415. o_proto = "UNKNOWN"
  416. else:
  417. #print("Layer:", xxl1.name)
  418. o_proto = layerukn.name
  419. #o_proto = "UNKNOWN"
  420. if packet[0][1].version == 4:
  421. packlen = str(packet[0][1].len)
  422. if packet[0][1].version == 6:
  423. packlen = str(packet[0][1].plen)
  424. trenner = " : " if len(o_payload) > 0 else " "
  425. if o_dir == 1:
  426. if numeric == False:
  427. #if res_cache.has_key(packet[0][1].dst):
  428. if packet[0][1].dst in res_cache:
  429. rem_name = res_cache[packet[0][1].dst]
  430. else:
  431. rem_name = _resolve_ip(packet[0][1].dst)
  432. else:
  433. rem_name = packet[0][1].dst
  434. #return "\033[1m "+str(packet[0].time)+" "+str(program)+"\033[0m" +"/"+ str(pid) + " - " + o_proto + ": " + packet[0][1].src + ":" + o_sport + "\033[1m\033[31m ->>> \033[0m" + rem_name + ":" + o_dport + " " + flags + " Len:" + str(packet[0][1].len) + " : " + o_payload
  435. return "\033[1m"+str(program)+"\033[0m" +"/"+ str(pid) + " - " + o_proto + ": " + packet[0][1].src + ":" + o_sport + "\033[1m\033[31m ->>> \033[0m" + rem_name + ":" + o_dport + " " + flags + " Len:" + packlen + trenner + o_payload
  436. else:
  437. if numeric == False:
  438. #if res_cache.has_key(packet[0][1].src):
  439. if packet[0][1].src in res_cache:
  440. rem_name = res_cache[packet[0][1].src]
  441. else:
  442. rem_name = _resolve_ip(packet[0][1].src)
  443. else:
  444. rem_name = packet[0][1].src
  445. return "\033[1m"+str(program)+"\033[0m" +"/"+ str(pid) + " - " + o_proto + ": " + packet[0][1].dst + ":" + o_dport + "\033[1m\033[36m <<<- \033[0m" + rem_name + ":" + o_sport + " " + flags + " Len:" + packlen + trenner + o_payload
  446. ## -- Ond denn s'Hooptprogramm
  447. # root check
  448. if not check_root():
  449. print("This program needs root privileges !\nThats because of reading the /proc filesystem and using libpcap functions.\nSo I give up\n")
  450. conf.sniff_promisc=0
  451. conf.sniff_promisc=0
  452. sys.exit()
  453. # get the interfaces
  454. #ifaces = subprocess.getoutput("ls /sys/class/net")
  455. #iface_list = ifaces.split('\n')
  456. iface_list = get_if_list()
  457. iface = conf.route.route("0.0.0.0")[0]
  458. rfilter = "ip or ip6"
  459. print("")
  460. # commandline params
  461. parser = argparse.ArgumentParser(description='sisniff V'+VERSION+"\n2017-2026 by sigi <https://wiki.zweiernet.ch/wiki/sisniff>",
  462. formatter_class=argparse.RawDescriptionHelpFormatter)
  463. parser.add_argument('-i', help="Interface", choices=iface_list)
  464. parser.add_argument('-n', help="Do not resolve IP-Addresses", action="store_true")
  465. parser.add_argument('-P', help="Don't put interface into promiscuous mode", action="store_true")
  466. parser.add_argument('-p', help='Filter by program name (accepts * for matching) ([not-] negates)', type=str, metavar='program|not-program')
  467. parser.add_argument('-4', dest='v4', help="Only IPv4", action="store_true")
  468. parser.add_argument('-6', dest='v6', help="Only IPv6", action="store_true")
  469. parser.add_argument('-H', help="Show HTTP Payload", action="store_true")
  470. parser.add_argument('-Hl', help="Show HTTP Payload, long output", action="store_true")
  471. parser.add_argument('-D', help="Show DNS Payload", action="store_true")
  472. parser.add_argument('filter', nargs='?', help="Filter (BPF syntax) on top of IP (in dbl-quotes \"...\")", type=str)
  473. args = parser.parse_args()
  474. if args.i:
  475. iface = args.i
  476. if args.n:
  477. numeric = True
  478. if args.v4:
  479. rfilter = "ip"
  480. if args.v6:
  481. rfilter = "ip6"
  482. if args.H:
  483. payloadH = True
  484. if args.Hl:
  485. payloadH = True
  486. payloadHl = True
  487. if args.D:
  488. if have_DNSLIB:
  489. payloadDNS = True
  490. else:
  491. print("Missing 'python3-dnslib': DNS-Payload not available.")
  492. if args.filter:
  493. fillter = " and (" + args.filter + ")"
  494. print("\033[1m> Applying Filter: \"" + rfilter + fillter + "\"\033[0m")
  495. if args.p:
  496. filter_prog = args.p
  497. have_filter_prog = False
  498. have_filter_progn = False
  499. have_filter_progn1 = False
  500. have_filter_progn2 = False
  501. have_filter_progn3 = False
  502. have_filter_progn4 = False
  503. have_filter_prog1 = False
  504. have_filter_prog2 = False
  505. have_filter_prog3 = False
  506. have_filter_prog4 = False
  507. if filter_prog.startswith('not-'):
  508. filter_progn = filter_prog[4:]
  509. have_filter_progn = True
  510. if filter_progn.startswith('*') and filter_progn.endswith('*'):
  511. have_filter_progn1 = True
  512. elif filter_progn.startswith('*') and not filter_progn.endswith('*'):
  513. have_filter_progn2 = True
  514. elif not filter_progn.startswith('*') and filter_progn.endswith('*'):
  515. have_filter_progn3 = True
  516. elif not filter_progn.startswith('*') and not filter_progn.endswith('*'):
  517. have_filter_progn4 = True
  518. else:
  519. have_filter_prog = True
  520. if filter_prog.startswith('*') and filter_prog.endswith('*'):
  521. have_filter_prog1 = True
  522. elif filter_prog.startswith('*') and not filter_prog.endswith('*'):
  523. have_filter_prog2 = True
  524. elif not filter_prog.startswith('*') and filter_prog.endswith('*'):
  525. have_filter_prog3 = True
  526. elif not filter_prog.startswith('*') and not filter_prog.endswith('*'):
  527. have_filter_prog4 = True
  528. no_promisc = ""
  529. if args.P:
  530. conf.sniff_promisc = conf.promisc = 0
  531. no_promisc = " (disabled promiscuous mode)"
  532. # local addresses
  533. if args.v6:
  534. MYADDRS=[]
  535. xMYADDRS = []
  536. else:
  537. MYADDRS = _remove_empty(os.popen("ip addr show " + iface + " | egrep 'inet ' | awk '{{print $2}}' | awk -F'/' '{{print $1}}'").read().split())
  538. MYADDRS.append('0.0.0.0')
  539. MYADDRS.append('127.0.0.1')
  540. xMYADDRS = [_ip_hexrev(x) for x in MYADDRS]
  541. if args.v4:
  542. MYADDRS6=[]
  543. else:
  544. #MYADDRS6 = _remove_empty(os.popen("ip addr show " + iface + " | egrep 'inet6' | grep -vi fe80 | awk '{{print $2}}' | awk -F'/' '{{print $1}}'").read().split())
  545. MYADDRS6 = _remove_empty(os.popen("ip addr show " + iface + " | egrep 'inet6' | awk '{{print $2}}' | awk -F'/' '{{print $1}}'").read().split())
  546. MYADDRS6.append(':::')
  547. MYADDRS6.append('::1')
  548. MYADDRS = MYADDRS + MYADDRS6
  549. xMYADDRS = xMYADDRS + [_to_v6_proc(expand_v6(x)) for x in MYADDRS6]
  550. print("> My IP-Addresses: " + str(MYADDRS))
  551. print("> Listening on: " + iface + no_promisc)
  552. # confirmed connections cache (ringboffer)
  553. conn_cache = []
  554. cc_maxlen = 20
  555. # resolver cache
  556. res_cache = {}
  557. n_try = 3
  558. print("")
  559. print("Prog/PID mavericks: \033[1m?/?\033[0m = No entry in /proc/net/xxx; \033[1m-/-\033[0m = No PID for Inode found; \033[1m./.\033[0m = Inode=0;")
  560. print("")
  561. print("Program/PID: Local addr:port <<->> Remote addr:port [Flags] Len:length : [Payload]")
  562. print("----------------------------------------------------------------------------------")
  563. # sniff, filtering for IP traffic
  564. try:
  565. sniff(filter=rfilter+fillter,iface=iface,prn=doPackets, store=0)
  566. except Exception as e:
  567. print("\n \033[1msniff() Error: " + str(e) + "\033[0m \n")
  568. traceback.print_exc()
  569. ## -- oond denn isch schloss