흥미로운 툴 하나를 발견하여 소개합니다. 일반적인 packet generating tool의 일종으로 보시면 됩니다.
http://certteamfast.blogspot.com/2011/11/tool-replaypcap.html
재미있는 것이 IPv4 packet을 IPv6 packet으로 변환하는 기능이 있네요.
src ip는 172.16.90.20(제 자신 IP) 이고 dst ip는 1.1.1 인데 화면 아래 부분에 dst ip가 잘못 나온 듯...
프로그램의 제작에 도움이 될까 하여 살포시 버그 리포팅을 해 봅니다. IPv6 변환하여 ICMP packet을 쏠 때, checksum이 틀렸다고 나오네요. IPv6에 대한 checksum은 구체적으로 어떻게 계산이 되는지 저도 잘 모르겠군요. 무조건 0xffff 인가?
관련 파일 첨부합니다. pcap 파일의 Mac이나 IP 정보를 가리거나 바꾸는 등의 짓은 안합니다. 대수로운 정보도 아니고, 어차피 남들에게 알려 줘도 상관 없음. ^^
ping.pcap : "ping 1.1.1.1" 을 때려서 잡은 원본 파일. packet 갯수는 4개임(깔끔하게~ 필요한 패킷만 저장해 주는 센스).
ping_replay.pcap : ReplayPcap 프로그램을 이용하여 packet generating한 파일. packet 갯수는 맹 4개.
안녕하십니까 협군 입니다.^^
진심으로 버그 리포팅 감사드립니다.
리포팅 해주신 부분에 대해 수정 및 기능 개선을 하였습니다.
또한 /MT 로 해서 빌드하였습니다.
언제든 버그리포팅은 감사히 받겠습니다.
그럼 좋은 하루 보내세요^^
두번째 버그 나갑니다. ^^
udp_1481.pcap : src ip 10.1.1.1 dst ip 1.1.1.1 로 해서 udp 1481 바이트(모두 'A')를 보낸 파일.
udp_1481_replay.pcap : udp_1481.pcap 파일을 Route Mode로 해서 보낸 파일.
send_udp.zip : udp data를 보내는 C++ 소스 파일.
힌트 : 2번째 패킷에서 udp port로 분석이 된 16705를 hexa로 나타 내면 0x4141 임.
안녕하십니까 협군입니다.^^
무한한 관심 감사드립니다.
ㅎㅎ 제 실력이 미천하여 완벽한 프로그램을 만들지를 못했네요^^
우선 리포팅 해주신 부분을 확인하였습니다.
재생하신 pcap은 IP fragment 된 UDP 패킷 입니다.
flow view 부분에서 두번째 fragment 된 패킷을 UDP 패킷으로 인지하여 0x4141 을 포트로 보여주는 것 같습니다.
툴 자체의 flow view는 현재 수정중이며 조작된 패킷에 대한 view는 어떻게 처리할 것인지 생각 중에 있습니다.
정상 패킷이라는 전제하에 view를 만들어서 fragment 된 패킷은 다르게 보일수도 있습니다.
해당 부분은 ver 0.2 에서 최대한 적용하도록 해보겠습니다.^^
또한 질문에 대한 답변도 첨부하겠습니다.
IPv6 는 IP 헤더에 체크섬이 존재하지 않습니다.
TCP UDP ICMP 체크섬은 ipv4 와 동일하나 체크섬 계산시 가상헤더 부분이 조금 틀려집니다.
무한한 관심 가져주신데에 다시 한번 감사드리며 기분좋은 하루 보내세요 (_ _ )
ㅎㅎㅎ 네
말씀해주신 부분 많이 반영하여 ver 0.2 에 적용 하도록 해보겠습니다(__)
깊은 관심 가져주셔서 다시한번 감사드립니다(__)
한가지 더 힌트를 더 드리자면
1. 일반적으로 packet이 Router를 경유하게 되면 TTL이 하나 감소하게 됩니다. 이 경우 IP header의 내용이 변하게 되므로 IP checksum 계산을 다시해 줘야 겠죠.
2. NAT(PAT)장비에서는 IP(혹은 port) 변환 작업까지 일어 나게 됩니다. 이 경우(협군님이 만든 프로그램에서도) 4바이트, 혹은 8바이트의 변환이 일어 나게 되는데요, 이렇게 되면 TCP나 UDP 헤더의 checksum까지고 다시 계산을 해 줘야 하는 불상사(?)가 발생합니다. 아시겠지만 TCP나 UDP의 checksum은 payload까지 전부를 다 봐야 하는 부담이 있죠.
이를 위해서 변경된 부분만을 가지고 checksum을 재계산해 주는 공식이 있습니다(16bit 단위로 계산을 함).
UINT16 recalculateChecksum(UINT16 oldChecksum, UINT16 oldValue, UINT16 newValue)
{
UINT32 sum;
sum = oldValue + (~newValue & 0xFFFF);
sum += oldChecksum;
sum = (sum & 0xFFFF) + (sum >> 16);
return (UINT16)(sum + (sum >> 16));
}