본문 바로가기

리눅스 커널/네트워크

Check Sum Layer 4

네트워크에서 패킷 전송 후 수신함에 있어 비트 에러 감지를 위해 체크섬을 사용한다.

체크섬의 계산 과정은 다음과 같다.

 

패킷을 2바이트 단위로 접근 하여 그 값을 더해 나가는데,

Carry가 발생하면 이 값을 다시 더해 나가는 것이다.

이 후 마지막 2바이트에 대해서도 계산을 마무리 하면 1의 보수를 취하면 된다.

 

이를 코드로 구현하면 다음과 같다.

unsigned short cksum(unsigned char * buff, int len)
{
	unsigned short * buf = (unsigned short *)buff;
	unsigned int sum = 0;

	for (; len > 0; len -= 2)
	{
		if (len == 1)
			sum += (unsigned short)(*(unsigned char *)buf);
		else
			sum += *(buf++);

		while (sum & 0xffff0000)
		{
			unsigned int carry = (sum & 0xffff0000) >> 16;
			sum &= 0x0000ffff;
			sum += carry;
		}	
	}

	return (unsigned short)~sum;
}

위 코드는 길이가 홀수인 경우까지 고려한 것이다.

IP헤더의 경우 checksum 필드만 0으로 초기화 하고, IP헤더의 시작 주소와 전체 길이를 전달하면 쉽게 구할 수 있지만

 

TCP, UDP헤더의 경우는 그 계산방식이 약간 다르다.

두 경우 모두 헤더 앞에 아래와 같은 가상의 헤더를 붙여서 계산해야 한다.

Reserved는 0으로 초기화 하면되고,

TCP Segment Length는 TCP헤더의 길이와 상위 계층에 데이터 길이의 합으로 설정해야 한다. 

 

 

참조

http://www.ktword.co.kr/abbr_view.php?m_temp1=1477

http://www.tcpipguide.com/free/t_TCPChecksumCalculationandtheTCPPseudoHeader-2.htm



'리눅스 커널 > 네트워크' 카테고리의 다른 글

Wireless packet capture  (0) 2021.10.24
TCP Handshake  (0) 2021.10.24
netlink example  (0) 2021.10.24
promiscuous mode  (0) 2021.10.24
DHCP  (0) 2021.10.24