{ int sum=0; // 총 합계. int nleft=len; // 인자로 받은 len. u_short *w=addr; // 인자로 받은 addr의 주소를 저장. u_short answer=0; // 최종적으로 리턴되는 값.
// nleft만큼 sum에 *w의 값을 더함. while (nleft > 1){ sum += *w++; nleft -= 2; }
// nleft가 홀수라서 값이 남을 경우 추가로 더해줌. if (nleft == 1){ *(u_char *)(&answer) = *(u_char *)w ; sum += answer; }
sum = (sum >> 16) + (sum & 0xffff); // 상위 16비트와 하위 16비트를 더함. sum += (sum >> 16); // carry bit 값을 더함. answer = ~sum; // 값을 반전 시킴. return(answer); // 리턴. }
USHORT checksum(USHORT *buffer, int size) { unsigned long cksum=0;
while(size >1) { cksum += *buffer++; size -= sizeof(USHORT); }
if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); } |
checksum을 하고자 하는 패킷 데이타의 포인터값을 USHORT *buffer에 넣어주시고, 해당 데이타 총 사이즈를 size에 넣어주시면
됩니다...그러면 checksum값이 USHORT 형으로 리턴되는데 그 값을 패킷에 있는 해당 checksum 필드에 넣어주시면 됩니다...
u_short ip_sum_calc( u_short len_ip_header, u_short * buff )
{
u_short word16;
u_int sum = 0;
u_short i;
// make 16 bit words out of every two adjacent 8 bit words in the packet
// and add them up
for( i = 0; i < len_ip_header; i = i+2 )
{
word16 = ( ( buff[i]<<8) & 0xFF00 )+( buff[i+1] & 0xFF );
sum = sum + (u_int) word16;
}
// take only 16 bits out of the 32 bit sum and add up the carries
while( sum >> 16 )
sum = ( sum & 0xFFFF ) + ( sum >> 16 );
// one's complement the result
sum = ~sum;
return ((u_short) sum);
}
void main()
{
unsigned short chksum;
u_short ipdata[20]; //checksum을 계산할기위한 버퍼
ip_header *myih;
char *ptr;
myih = (ip_header*)malloc(sizeof(myih));
ptr = (char*)myih;
printf("\n");
// IP 패킷에 대한 정보들을 저장한다.
myih->ip_header_len=0x5;
myih->ip_version = 0x4;
myih->ip_tos = 0x0;
myih->ip_total_length = ntohs(0x30);
myih->ip_id = htons(0x00);
myih->ip_frag_offset = 0;
myih->ip_more_fragment = 0;
myih->ip_dont_fragment = 1;
myih->ip_reserved_zero =0;
myih->ip_frag_offset1 =0;
myih->ip_ttl = 0x3c;
myih->ip_protocol = 0x06;
myih->ip_checksum = 0;
myih->ip_srcaddr.S_un.S_addr = inet_addr(src_ip);
myih->ip_destaddr.S_un.S_addr = inet_addr(dest_ip);
//모든 정보를 세팅하고 체크섬을 구한다.
int i;
// 1byte 단위 값을 2바이트 배열에 저장함
for (i = 0; i < 20; i ++) {
ipdata[i] = *(unsigned char*)ptr++;
}
myih->ip_checksum = ip_sum_calc(20, ipdata);
printf("checksum = %x\n",myih->ip_checksum);
}
char Check_CheckSum(char check_data[])//체크섬 확인함수
{
command = RX2_BUFFER[10];
while(stop)
{
if(check_data[i]=='*')
{
return check_data[i+1];
stop = 0;
break;
}
i++;
}
return 'a';
}
char Check_Sum(char check_data[])//checksum 게산 함
{
char checksum = 0x00;
int step= 1;
int str=1;
while(step)
{
if(check_data[str]==' ')//*가 나오면 체크섬 게산 종료
{
step = 0;
break;
}
else
{
checksum = checksum ^ check_data[str];
str++;
}
}
return checksum;
}