No Interfaces Available In Wireshark Mac OS X

No Interfaces Available In Wireshark Mac OS X

No Interfaces Available In Wireshark Mac OS X
Many new Wireshark users on Mac OS X run into an issue where no interfaces show up when trying to begin packet capture. If you attempt to manually input an interface (such as en0) this error will occur:

The capture session could not be initiated ((no devices found) /dev/bpf0: Permission denied).

To have the interfaces show up properly you’ll need to widen the permissions on the Berkeley packet filter (BPF). By default they look like this:
  1. crw-------1 rootwheel 23, 0 Jan 31 13:47 /dev/bpf0
复制代码
We need the filter to be readable by non-root, so open Terminal.app and run this command:
  1. sudo chmod 644 /dev/bpf*
复制代码
Unfortunately every time you reboot this will reset, but if you are a frequent user of Wireshark you can add the ChmodBPF StartupItem to alter them automatically (available in the Utilities folder on the Wireshark disk image). To install you’ll need to follow two steps.

First, drag the ChmodBPF folder to the StartupItems alias in the same folder (or drag it to /Library/StartupItems directly). Type your password to authenticate and move the folder into the correct location.

The second requirement is only for 10.6+ users. Starting with Snow Leopard the security permissions of StartupItems are being enforced. Scripts that do not have the proper owner and group will receive this error:

Insecure Startup Item disabled. – “/Library/StartupItems/ChmodBPF” has not been started because it does not have the proper security settings

The proper security settings are ownership of the scripts by root and group of wheel.1 To set them:
  1. sudo chown -R root:wheel ChmodBPF
复制代码
The correct settings for startup items can be found in this Apple KB article ↩
from:http://langui.sh/2010/01/31/no-i ... wireshark-mac-os-x/

求解ChmodBPF是什么东西?英文能力有限,大概理解就是capture session所需要的/dev/bpf*没有权限,需要赋予权限,但是从启后还从新需要直接赋予权限的命令,那问提到/Library/StartupItems/这里,应该类似win下的启动菜单,但是文中ChmodBPF是何物?是自写的一个处理这个问题的shell脚本还是?那位童鞋了解过 谢谢了:)
为什么要获取MAC,为什么要构造完整报文帧,请换一种方法 #!/usr/bin/env python3 """ mdns_query_generator_improved.py 不依赖 Scapy,使用原生 socket 构造 mDNS 查询。 - 根据 IP 自动查找网络接口 - 跨平台权限检查(Windows/Linux) - 多线程并发发送 """ import argparse import threading import time import random import sys import socket import struct from struct import pack # 全局变量 stop_event = threading.Event() MCAST_ADDR = "224.0.0.251" MCAST_PORT = 5353 IP_TTL = 255 def is_admin(): """跨平台检查管理员/root 权限""" try: if sys.platform == "win32": import ctypes return ctypes.windll.shell32.IsUserAnAdmin() != 0 else: return hasattr(os, 'geteuid') and os.geteuid() == 0 except Exception: return False def get_interface_by_ip_ioctl_linux(ip): """Linux 下通过 ioctl(SIOCGIFCONF) 查找接口名""" try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # SIOCGIFCONF: 获取所有接口信息 ifs = fcntl.ioctl(s.fileno(), 0x8912, bytes(4096)) s.close() # 每个 ifreq 结构体约 40 字节(if_name + sa) for i in range(0, len(ifs), 40): data = ifs[i:i+40] if len(data) < 40: continue ifname_bytes = data[:16].split(b'\x00', 1)[0] ifname = ifname_bytes.decode('utf-8') addr_data = data[20:24] # sin_addr 在结构体中的偏移 ip_if = socket.inet_ntoa(addr_data) if ip_if == ip: return ifname except Exception as e: print(f"[ioctl] Error: {e}") return None def get_interface_by_ip_netifaces(ip): """使用 netifaces 查找接口""" try: import netifaces for iface in netifaces.interfaces(): addrs = netifaces.ifaddresses(iface) if netifaces.AF_INET in addrs: for addr_info in addrs[netifaces.AF_INET]: if addr_info['addr'] == ip: return iface except ImportError: return None except Exception as e: print(f"[netifaces] Error: {e}") return None return None def get_interface_by_ip(ip): """自动根据 IP 查找对应接口名(优先 netifaces,fallback 到 ioctl)""" # 方法 1: netifaces iface = get_interface_by_ip_netifaces(ip) if iface: return iface # 方法 2: Linux ioctl if sys.platform.startswith("linux"): iface = get_interface_by_ip_ioctl_linux(ip) if iface: return iface # 方法 3: 尝试用 UDP connect 推断出口接口(启发式) try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 53)) local_ip = s.getsockname()[0] s.close() if local_ip == ip: # 再试一次 ioctl(适用于本机默认路由接口) return get_interface_by_ip_ioctl_linux(ip) except Exception: pass return None def mac_str_to_bytes(mac): """MAC 字符串转 bytes""" return bytes(int(b, 16) for b in mac.split(':')) def ip_str_to_bytes(ip): """IPv4 转 bytes""" return bytes(map(int, ip.split('.'))) def ip_to_int(ip): """IP 转整数""" return sum([int(b) << (8 * (3 - i)) for i, b in enumerate(ip.split('.'))]) def checksum(data): """校验和计算""" if len(data) % 2 == 1: data += b'\0' chk = 0 for i in range(0, len(data), 2): chk += (data[i] << 8) + data[i + 1] while chk >> 16: chk = (chk & 0xFFFF) + (chk >> 16) return ~chk & 0xFFFF def build_dns_query(qname, qtype=12): # 12 = PTR def encode_name(name): result = b'' for part in name.encode().split(b'.'): result += bytes([len(part)]) + part return result + b'\0' header = pack('>HHHHHH', 0, 0x0100, 1, 0, 0, 0) question = encode_name(qname) + pack('>HH', qtype, 1) return header + question def build_udp_packet(sport, dport, data): length = 8 + len(data) udp_header = pack('>HHH H', sport, dport, length, 0) pseudo_header = ip_str_to_bytes(src_ip_global) + ip_str_to_bytes(MCAST_ADDR) + \ pack('>BBH', 0, 17, length) chk_data = pseudo_header + udp_header[:8] + b'\0\0' + data csum = checksum(chk_data) udp_header = pack('>HHH H', sport, dport, length, csum) return udp_header + data def build_ip_packet(src, dst, proto, payload): version_ihl_tos = 0x45 tot_len = 20 + len(payload) iden = random.randint(0, 0xFFFF) frag = 0 ttl = IP_TTL src_addr = ip_str_to_bytes(src) dst_addr = ip_str_to_bytes(dst) header = pack('!BBHHHBBHII', version_ihl_tos, 0, tot_len, iden, frag, ttl, proto, 0, ip_to_int(src), ip_to_int(dst)) chk = checksum(header) header = pack('!BBHHHBBHII', version_ihl_tos, 0, tot_len, iden, frag, ttl, proto, chk, ip_to_int(src), ip_to_int(dst)) return header + payload # 全局用于保存源 IP src_ip_global = None def get_interface_mac(iface_name): """获取接口 MAC 地址""" if sys.platform.startswith("linux"): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', iface_name.encode('utf-8')[:15])) return bytes(info[18:24]) except Exception as e: print(f"Failed to get MAC of {iface_name}: {e}") return None return None def sender_thread(thread_id, service, rate, iface_name, src_ip): global src_ip_global src_ip_global = src_ip try: my_mac = get_interface_mac(iface_name) if not my_mac: print(f"[Thread {thread_id}] Cannot get MAC address.") stop_event.set() return except Exception as e: print(f"[Thread {thread_id}] Interface error: {e}") stop_event.set() return eth_hdr = mac_str_to_bytes("01:00:5e:00:00:fb") + my_mac + pack('!H', 0x0800) dns_query = build_dns_query(service, qtype=12) udp_pkt = build_udp_packet(MCAST_PORT, MCAST_PORT, dns_query) ip_pkt = build_ip_packet(src_ip, MCAST_ADDR, 17, udp_pkt) packet = eth_hdr + ip_pkt # 仅 Linux 支持 AF_PACKET 发送 if not sys.platform.startswith("linux"): print(f"[Thread {thread_id}] Non-Linux platform: simulating send") interval = 1.0 / rate if rate > 0 else 0 while not stop_event.is_set(): print(f"[SIM] Sending mDNS query from {src_ip} via {iface_name}") time.sleep(interval) return try: sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0800)) sock.bind((iface_name, 0)) except PermissionError: print(f"[ERROR] Permission denied. Run as root/administrator.") stop_event.set() return except Exception as e: print(f"[Socket] Create failed: {e}") stop_event.set() return print(f"[Thread {thread_id}] Started sending on {iface_name}") interval = 1.0 / rate if rate > 0 else 0 while not stop_event.is_set(): try: sock.send(packet) except Exception as e: print(f"[Send] Failed: {e}") break if interval > 0: time.sleep(interval) def main(): parser = argparse.ArgumentParser(description="mDNS Query Generator (No Scapy, Auto IFACE)") parser.add_argument("--service", default="_http._tcp.local.", help="Service type to query (PTR)") parser.add_argument("--clients", type=int, default=100, help="Number of concurrent threads") parser.add_argument("--rate", type=float, default=1.0, help="Queries per second per client") parser.add_argument("--duration", type=int, default=60, help="Duration in seconds") parser.add_argument("--ip", required=True, help="Source IP address (used to auto-find interface)") args = parser.parse_args() # 步骤 1: 检查权限 if not is_admin(): print("[WARNING] May lack permission to send raw packets. Please run as admin/root.") # 步骤 2: 根据 IP 自动查找接口 iface_name = get_interface_by_ip(args.ip) if not iface_name: print(f"[ERROR] Cannot find interface for IP {args.ip}") print("Available interfaces may not have this IP assigned.") sys.exit(1) print(f"[INFO] Found interface '{iface_name}' for IP {args.ip}") # 步骤 3: 启动多线程发送器 print(f"[INFO] Starting {args.clients} clients, {args.rate} qps/client, duration={args.duration}s") threads = [] for i in range(args.clients): t = threading.Thread( target=sender_thread, args=(i, args.service, args.rate, iface_name, args.ip), daemon=True ) t.start() threads.append(t) start_time = time.time() try: while time.time() - start_time < args.duration and not stop_event.is_set(): time.sleep(0.5) except KeyboardInterrupt: print("\n[INFO] Interrupted by user.") stop_event.set() stop_event.set() print("Waiting for threads to finish...") for t in threads: t.join(timeout=2.0) print("Done.") if __name__ == "__main__": # 导入条件依赖 if sys.platform.startswith("linux"): import fcntl main() "python mdns_query.py --ip 192.168.2.2 --clients 10 --rate 2 --duration 30"
最新发布
10-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值