import struct
import socket
from header.eth import *
from header.ip import *
from header.icmp import *
def make_chksum( header ): # 체크섬을 구하는 함수
size = len( header )
if size % 2:
header = header + b'\x00'
size = len( header )
size = size // 2
header = struct.unpack('!' + str(size) + 'H', header )
chksum = sum( header )
carry = chksum & 0xFF0000
carry = carry >> 16
while carry != 0:
chksum = chksum & 0xFFFF
chksum = chksum + carry
carry = chksum & 0xFF0000
carry = carry >> 16
chksum = chksum ^ 0xFFFF
return chksum
#클래스 객체 생성
eth1 = Eth()
ip1 = Ip()
echo1 = Echo()
ip2 = Ip()
ip3 = Ip()
#icmp헤더 작성
echo1.type = 8 #2byte
echo1.code = 0 #2byte
echo1.chksum = 0 #4byte
#모든 Segment들을 8byte의 크기로 맞추어서 전송시키도록 하자 ( ICMP헤더 8 + payload 16 => 3개의 Segment )
echo1.payload = 'ccccccccdddddddd' (16byte)
echo1.chksum = make_chksum( echo1.header )
echo1.payload = ''
ip1.ver = 4
ip1.length = 20
ip1.service = 0
ip1.total = 20 + len( echo1.header )
ip1.id = 0x1234
ip1.flag = 1
ip1.offset = 0 # 첫번째 Segment이므로 0 , 기준이 된다
ip1.ttl = 64
ip1.type = 1
ip1.chksum = 0
ip1.src = '192.168.6.123'
ip1.dst = '192.168.6.41'
ip1.chksum = make_chksum( ip1.header )
#두번째 Segment
payload2 = 'cccccccc'.encode()
ip2.ver = 4
ip2.length = 20
ip2.service = 0
ip2.total = 20 + len( payload2 )
ip2.id = 0x1234
ip2.flag = 1 # 세번째 Segment가 존재하므로 1
ip2.offset = 8 # 첫번째 Segment의 크기만큼 이동된 거리 ( 2+2+4 )
ip2.ttl = 64
ip2.type = 1
ip2.chksum = 0
ip2.src = '192.168.6.123'
ip2.dst = '192.168.6.41'
ip2.chksum = make_chksum( ip2.header )
#세번째 Segment
payload3 = 'dddddddd'.encode()
ip3.ver = 4
ip3.length = 20
ip3.service = 0
ip3.total = 20 + len( payload3 )
ip3.id = 0x1234
ip3.flag = 0 # 현재 Segment가 마지막이므로 0
ip3.offset = 16 # 두번째 Segment의 크기만큼 이동된 거리 ( 8byte )
ip3.ttl = 64
ip3.type = 1
ip3.chksum = 0
ip3.src = '192.168.6.123'
ip3.dst = '192.168.6.41'
ip3.chksum = make_chksum( ip3.header )
#이더넷헤더 작성
eth1.dst = '00:0C:29:0C:AF:90'
eth1.src = '00:0C:29:F0:62:73'
eth1.type = 0x0800
eth1.src = '00:0C:29:F0:62:73'
eth1.type = 0x0800
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW )
sock.bind( ('eth0', socket.SOCK_RAW) )
sock.send( eth1.header + ip1.header + echo1.header ) #첫번째 Segment ( 8byte )
sock.send( eth1.header + ip2.header + payload2 ) #두번째 Segment ( 8byte )
sock.send( eth1.header + ip3.header + payload3 ) #세번째 Segment ( 8byte )