네트워크에서 패킷 전송 후 수신함에 있어 비트 에러 감지를 위해 체크섬을 사용한다.
체크섬의 계산 과정은 다음과 같다.
패킷을 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 |