unsigned short in_cksum(u_short *addr, int len)
{
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;
}