syn패킷보낼때 tcp 체크섬 계산

suner의 이미지

window 2000에서 rawsocket을 구현해 보았는데요
현재 syn 패킷이 발송됬다고 이더렐로 잡힙니다.
그러나 체크섬을 계산하지 못해서 syn + ack가 넘어오지 않습니다.
아래는 인터넷에서 찾은 소스인데 ip는 체크섬이 제대로 되는데
tcp가 체크섬이 안되네요, 가상 해더 역시 인터넷에 있는 소스를 구해서 적용해 보았습니다.
뭐가 틀렸는지 알려 주시면 감사하겠습니다.

//raw tcp packet crafter
 
#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h"  //IP_HDRINCL is here
#include "conio.h"
 
#pragma comment(lib,"ws2_32.lib")  //winsock 2.2 library
 
typedef struct ip_hdr
{
    unsigned char  ip_header_len:4;  // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
    unsigned char  ip_version   :4;  // 4-bit IPv4 version
    unsigned char  ip_tos;           // IP type of service
    unsigned short ip_total_length;  // Total length
    unsigned short ip_id;            // Unique identifier 
 
	unsigned char  ip_frag_offset   :5;        // Fragment offset field
 
	unsigned char  ip_more_fragment :1;
	unsigned char  ip_dont_fragment :1;
	unsigned char  ip_reserved_zero :1;
 
    unsigned char  ip_frag_offset1;    //fragment offset
 
	unsigned char  ip_ttl;           // Time to live
    unsigned char  ip_protocol;      // Protocol(TCP,UDP etc)
    unsigned short ip_checksum;      // IP checksum
    unsigned int   ip_srcaddr;       // Source address
    unsigned int   ip_destaddr;      // Source address
}   IPV4_HDR, *PIPV4_HDR, FAR * LPIPV4_HDR;
 
 
// TCP header
typedef struct tcp_header 
{ 
	unsigned short source_port;  // source port 
	unsigned short dest_port;    // destination port 
	unsigned int   sequence;     // sequence number - 32 bits 
	unsigned int   acknowledge;  // acknowledgement number - 32 bits 
 
	unsigned char  ns   :1;          //Nonce Sum Flag Added in RFC 3540.
	unsigned char  reserved_part1:3; //according to rfc
	unsigned char  data_offset:4;    /*The number of 32-bit words in the TCP header. 
									   This indicates where the data begins. 
									   The length of the TCP header is always a multiple 
									   of 32 bits.*/
 
	unsigned char  fin  :1;      //Finish Flag
	unsigned char  syn  :1;      //Synchronise Flag
	unsigned char  rst  :1;      //Reset Flag
	unsigned char  psh  :1;      //Push Flag 
	unsigned char  ack  :1;      //Acknowledgement Flag 
	unsigned char  urg  :1;      //Urgent Flag
 
	unsigned char  ecn  :1;      //ECN-Echo Flag
    unsigned char  cwr  :1;      //Congestion Window Reduced Flag
 
	////////////////////////////////
 
	unsigned short window;  // window 
	unsigned short checksum;  // checksum 
	unsigned short urgent_pointer;  // urgent pointer 
}   TCP_HDR , *PTCP_HDR , FAR * LPTCP_HDR , TCPHeader , TCP_HEADER;
 
#define u_int16_t unsigned short
#define u_int32_t unsigned int
#define u_int8_t unsigned char
#define n_short u_short
 
struct pseudohdr {
u_int32_t saddr;
u_int32_t daddr;
u_int8_t useless;
u_int8_t protocol;
u_int16_t tcplength;
};
 
unsigned short in_chksum(unsigned short *addr, int len)
{
	int sum = 0;
	int nleft = len;
	u_short *w=addr;
	u_short answer = 0;
	while(nleft >1)
	{
		sum +=*w++;
		nleft -= 2;
	}
	if(nleft == 1)
	{
		*(u_char *)(&answer) = *(u_char *)w;
		sum += answer;
	}
	sum = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
	answer = ~sum;
	return (answer);
}
 
int main()
{
	char host[100],buf[512],*data=NULL,source_ip[20]; //buf is the complete packet
	SOCKET s;
	int k=1;
	struct pseudohdr *pseudo_header;
	IPV4_HDR *v4hdr=NULL;
	TCP_HDR  *tcphdr=NULL;
 
	int payload=400 , optval;
	SOCKADDR_IN dest;
	hostent *server;
	struct sockaddr_in target_addr;
	struct sockaddr_in your_addr;
 
	//Initialise Winsock
	WSADATA wsock;
	printf("\nInitialising Winsock...");
	if (WSAStartup(MAKEWORD(2,2),&wsock) != 0)
	{
		fprintf(stderr,"WSAStartup() failed");
        exit(EXIT_FAILURE); 
	} 
	printf("Initialised successfully.");
	////////////////////////////////////////////////
 
	//Create Raw TCP Packet
	printf("\nCreating Raw TCP Socket...");
	if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==SOCKET_ERROR)
	{
		printf("Creation of raw socket failed.");
		return 0;
	}
	printf("Raw TCP Socket Created successfully.");
	////////////////////////////////////////////////
 
	//Put Socket in RAW Mode.
	printf("\nSetting the socket in RAW mode...");
	if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
	{
		printf("failed to set socket in raw mode.");
		return 0;
	}
	printf("Successful.");
	////////////////////////////////////////////////
 
 
	//Target Hostname
	printf("\nEnter hostname : ");
	//gets(host);
	printf("\nResolving Hostname...");
	/*
	if((server=gethostbyname(host))==0)
	{
		printf("to resolve.");
		return 0;
	}
	*/
	/*
	dest.sin_family = AF_INET;
	dest.sin_port   = htons(50000);  //your destination port
	memcpy(&dest.sin_addr.s_addr,server->h_addr,server->h_length);
	printf("Resolved.");
	*/
	/////////////////////////////////////////////////
	dest.sin_family = AF_INET;
	dest.sin_addr.s_addr = inet_addr("192.168.10.102");
	dest.sin_port = htons(25);
	printf("\nEnter Source IP : ");
	//gets(source_ip);
 
	target_addr.sin_family = AF_INET;
	target_addr.sin_addr.s_addr = inet_addr("192.168.10.102");
	target_addr.sin_port = htons(25);
	your_addr.sin_addr.s_addr = inet_addr("192.168.10.101");
	your_addr.sin_port = htons(30045);
 
 
	v4hdr = (IPV4_HDR *)buf;  //lets point to the ip header portion
	memset((char *)v4hdr, 0, sizeof(v4hdr));
	tcphdr = (TCP_HDR *)&buf[sizeof(IPV4_HDR)]; //get the pointer to the tcp header in the packet
	//tcphdr = (TCP_HDR *)(buf + 20); //get the pointer to the tcp header in the packet
	memset((char *)tcphdr, 0, sizeof(tcphdr));
 
	tcphdr->source_port = htons(30045);
	tcphdr->dest_port = htons(25);
	tcphdr->cwr=0;
	tcphdr->ecn=0;
	tcphdr->urg=0;
	tcphdr->ack=0;
	tcphdr->psh=0;
	tcphdr->rst=0;
	tcphdr->syn=1;
	tcphdr->fin=0;
	tcphdr->ns=1;
	tcphdr->acknowledge = htonl(0);
	tcphdr->urgent_pointer = 0;
	tcphdr->sequence = GetCurrentProcessId();
	tcphdr->window = htons( 512 );
 
	//pseudo_header = (struct pseudohdr *)&buf[sizeof(struct tcp_header)];
	pseudo_header = (struct pseudohdr  *)((char *)tcphdr - sizeof(struct pseudohdr));
 
	pseudo_header->saddr = inet_addr("192.168.10.101");
	pseudo_header->daddr = inet_addr("192.168.10.102");
	pseudo_header->protocol = IPPROTO_TCP; 
	pseudo_header->tcplength = htons(sizeof(struct tcp_header)); 
 
	tcphdr->checksum = in_chksum((u_short *)pseudo_header,(sizeof(struct pseudohdr)+sizeof(struct tcp_header)));
 
	v4hdr->ip_version=4;
	v4hdr->ip_header_len=5;
	v4hdr->ip_tos    = 0;
	v4hdr->ip_total_length = htons ( sizeof(IPV4_HDR) + sizeof(TCP_HDR) + payload );
	v4hdr->ip_id     = htons(0);
	v4hdr->ip_frag_offset = 0;
	v4hdr->ip_frag_offset1 = 0;
	v4hdr->ip_reserved_zero = 0;
	v4hdr->ip_dont_fragment = 1;
	v4hdr->ip_more_fragment = 0;
	v4hdr->ip_ttl    = 8;
	v4hdr->ip_protocol = IPPROTO_TCP;
	v4hdr->ip_srcaddr  = inet_addr("192.168.10.101");
	v4hdr->ip_destaddr = inet_addr("192.168.10.102");
	v4hdr->ip_checksum = in_chksum((u_short *)&v4hdr, sizeof(ip_hdr));
 
 
	// Initialize the TCP payload to some rubbish
	//data = &buf[sizeof(IPV4_HDR) + sizeof(TCP_HDR)];
	//memset(data, '^', payload);
 
	printf("\nSending packet...\n");
 
 
	printf("  %d  packets send\n",k++);
	if((sendto(s , buf , sizeof(IPV4_HDR)+sizeof(TCP_HDR) + payload, 0, (SOCKADDR *)&dest, sizeof(dest)))==SOCKET_ERROR)
	{
		printf("Error sending Packet : %d",WSAGetLastError());
	}
	printf("success");
 
	return 0;
}
mdh2322의 이미지

tcp header뒤에 오는 데이터 부분에 대한 checksum계산이 안되는듯 보입니다.

그러나 이제 때는 왔다

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.