何:
生のソケット、すなわち生ソケット、データは、ネットワークトラフィック分析を聞くために、機械フレーム又はパケットネットワークカード上で受信され、有用な効果であることができます。
どこ:
これは、ソケット4通りの合計を作成している場合があります。
1.socket(PF_INET、SOCK_RAW、IPPROTO_TCP | IPPROTO_UDP | IPPROTO_ICMP)は、データを送受信するパケットのIP
ソケット(AF_INET、SOCK_RAW、IPPROTO_UDP)
ソケットはないローカルIP宛てされていないソフトフィルタを破棄するデータIP(非IPパケットを受信するローカル宛ての、マシンのIPパケットを宛先(TCP、UDP、ICMP、等)プロトコルタイプを受信しますパッケージ)は、データパケットを受信することができないユニットから送信されます。
TCP、UDP、ICMPを整理する必要があり、他のヘッドは、あなたが自分自身を送信するとき、あなたはのsetsockopt IPヘッダにパッケージ所有することができます。
pingプログラムに適し
2.socket(PF_PACKET、SOCK_RAW、htons(ETH_P_IP | ETH_P_ARP | ETH_P_ALL))は、受信したイーサネットデータフレームを送信します
ソケット(AF_PACKET、SOCK_RAW、htons(x))を
そのようなソケットを作成すると、ネットワークカード上のすべてのデータフレームを監視することができます。
ETH_P_IPは0x800 Aは、データフレームに機械式のMAC IPを受け取ります
ETH_P_ARP 0x806は唯一のマシン宛てのARP MACデータフレームのタイプを受け入れます
ETH_P_RARP 0x8035 RARPは機械フレームデータのMACのタイプを受け入れる運命
ETH_P_ALL 0x3のは、マシンから送信されたデータフレームのすべての種類を受け、すべての種類のIP ARP、RARPネイティブMACデータフレームに送られた受信。(ケース無差別モードが有効になっている、ローカルMACデータフレームに宛て以外を受け取ることになります)
3.socket(PF_PACKET、SOCK_DGRAM、htons(ETH_P_IP | ETH_P_ARP | ETH_P_ALL))は、(イーサネットヘッダを含まない)、受信したイーサネットデータフレームを送信します
ソケット(AF_PACKET、SOCK_DGRAM、htons(x))を
機能及び第二機能は類似しているが、イーサネットヘッダを含みません
彼パケットは、非IPプロトコルを充電することがあり
4.socket(PF_INET、SOCK_PACKET、htons(ETH_P_IP | ETH_P_ARP | ETH_P_ALL))
ソケット(AF_INET、SOCK_PACKET、htons(ETH_P_ALL))
一般的には、パケットキャプチャプログラムを使用
なぜ:
rawソケットと標準ソケットとの差:
オリジナルソケットはIPパケット処理コアを読み込むことはできませんが、唯一のデータTCPストリームソケットプロトコルを読み取ることができ、データグラムソケットは、データのみプロトコルUDPを読むことができます。だから、あなたがデータを送信するために、追加のプロトコルにアクセスしたい場合は、rawソケットを使用する必要があります。
どうやって:
Pythonは、単純なスニファを達成します
- プロミスキャスモードのNIC。
- キャプチャパケット。
- パケットを分析します。
- 閉じる無差別モード
import socket
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
# receive a package
print(s.recvfrom(65565))
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
分析IPパケット:
import socket
#抓捕
def sniffIpData():
host_ip = socket.gethostbyname(socket.gethostname()) #获取IP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) #创建套接字、可接受协议类型为UDP、TCP、ICMP、IP
sniffer.bind((host_ip, 0))
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) #设置套接字options、包装ip头部
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) #receive all package
recv_data, addr = sniffer.recvfrom(1500)
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) # disabled promiscuous mode
sniffer.close()
return recv_data
#解析
def decodeIpData(package):
ip_data = {}
#RFC791
ip_data['version'] = package[0] >> 4
ip_data['headLength'] = package[0] & 0x0f #& 按位与操作
ip_data['DSField'] = package[1]
ip_data['totalLength'] = (package[2] << 8) + package[3]
ip_data['identification'] = (package[4] << 8) + package[5]
ip_data['flag'] = package[6] >> 5
ip_data['moreFragment'] = ip_data['flag'] & 1
ip_data['dontFragment'] = (ip_data['flag'] >> 1) & 1
ip_data['fragmentOffset'] = ((package[6] & 0x1f) << 8) + package[7]
ip_data['TTL'] = package[8]
ip_data['protocol'] = package[9]
ip_data['headerCheckSum'] = (package[10] << 8) + package[11]
#以IP地址形式存储
ip_data['sourceAddress'] = "%d.%d.%d.%d" % (package[12], package[13], package[14], package[15])
ip_data['destinationAddress'] = "%d.%d.%d.%d" % (package[16], package[17], package[18], package[19])
ip_data['options'] = []
#根据headerLength求出options
if ip_data['headLength'] > 5: #一般来说此处的值为0101,表示头长度为20字节、若超出则大于5(0101)
temp = 5
while temp < ip_data['headLength']:
ip_data['options'].append(package[temp * 4] + 0)
ip_data['options'].append(package[temp * 4] + 1)
ip_data['options'].append(package[temp * 4] + 2)
ip_data['options'].append(package[temp * 4] + 3)
temp += 1
#根据totalLength求出data
ip_data['data'] = []
temp = ip_data['headLength'] * 4
while temp < ip_data['totalLength']:
ip_data['data'].append(package[temp])
temp += 1
return ip_data
package = sniffIpData()
data_decode = decodeIpData(package)
# for i, k in data_decode:
# print("%d:%d" % (i, k))
for key in data_decode.items():
print(key)
これまでのところ、光のバージョンが達成されました。