บทความล่าสุด
 AT90USB162 Prototype Board
 Codeblocks กับ Serial Port
 Image2GLCD โปรแกรมแปลงภาพสำหรับ Graphic LCD
 Codeblocks กับ Static library
 TinyRGB ควบคุม RGB LED ด้วย ATTINY2313
 การใช้ Capture Filter ใน Wireshark
 รูปแบบของ Intel hex file
 Codeblocks กับการใช้งานไฟล์ DLL
 การอัพเกรด firmware DV-393
 วิเคราะห์ระบบเครือข่ายด้วย Wireshark
 AVR JTAGICE
 บอร์ด AVRnet
 การคำนวณค่า Checksum
 การติดตั้ง CodeBlocks, wxWidgets, MinGW
Search by Google
Google
แลกเปลี่ยน Banner
ThaiEasyElec.com - จำหน่ายอุปกรณ์อิเล็กทรอนิกส์ , บทความอิเล็กทรอนิกส์  
เว็บไซต์อิเล็กทรอนิกส์-นานาสาระ   ศูนย์รวมของคนเล่นเน็ต
 
 
 



Web hosting by picoHosting
Codeblocks free C++ IDE.
    หลังจากที่แนะนำบอร์ด AVRnet ไปแล้ว บทความนี้จะอธิบายถึงการคำนวณค่า checksum ในโปรโตคอล IP, ICMP, TCP ว่ามีการคำนวณอย่างไร โดยผมจะใช้ฟังก์ชั่น software_checksum เป็นตัวอย่างสำหรับการคำนวณ
    ค่า checksum นี้ มีไว้สำหรับตรวจสอบความถูกต้องของข้อมูลที่ส่งไป ฝ่ายที่ส่งข้อมูลจะทำการคำนวณค่า checksum แล้วใส่ค่า checksum ลงไปใน header ของแต่ละโปรโตคอล เมื่อฝ่ายรับข้อมูล รับข้อมูลมาแล้วจะนำเอาค่า checksum นี้มาตรวจสอบข้อมูลที่รับมาว่าถูกต้องหรือไม่

Code:

WORD software_checksum(BYTE *rxtx_buffer, WORD len, DWORD sum)
{
	// build the sum of 16bit words
	while(len>1)
	{
		sum += 0xFFFF & (*rxtx_buffer<<8|*(rxtx_buffer+1));
		rxtx_buffer+=2;
		len-=2;
	}
	// if there is a byte left then add it (padded with zero)
	if (len)
	{
		sum += (0xFF & *rxtx_buffer)<<8;
	}
	// now calculate the sum over the bytes in the sum
	// until the result is only 16bit long
	while (sum>>16)
	{
		sum = (sum & 0xFFFF)+(sum >> 16);
	}
	// build 1's complement:
	return( (WORD) sum ^ 0xFFFF);
}
Function arguments
  • BYTE *rxtx_buffer เป็น pointer ที่ชี้ไปที่บัฟเฟอร์ โดยจะชี้ไปที่ตำแหน่งแรกของข้อมูลที่ต้องการนำมาคำนวณค่า checksum เช่น&rxtx_buffer[ IP_P ]
  • WORD len ขนาดของข้อมูลที่ต้องการนำมาคำนวณค่า checksum (เป็น bytes) เช่น sizeof(IP_HEADER) ขนาดของข้อมูลจะเท่ากับขนาดของ IP header
  • DWORD sum เป็นค่าเริ่มต้นของค่า checksum ตัวแปลนี้จะใช้งานก็ต่อเมื่อ ต้องการคำนวณค่า checksum ของโปรโตคอล TCP เท่านั้น สำหรับโปรโตคอล IP, ICMP ตัวแปลนี้จะต้องเป็น 0
Return value
  • ค่าที่ส่งกลับจากฟังก์ชั่นนี้จะเป็นค่า checksum ที่คำนวณได้
การทำงานของฟังก์ชั่น
  • ฟังก์ชั่นจะคำนวณค่า checksum แบบ 16-bits จนกว่าขนาดของข้อมูล (len ) จะน้อยกว่า 1-byte จึงหยุดคำนวณค่า checksum แล้วมาตรวจสอบว่ายังมีข้อมูลเหลืออีกหรือไม่


Code:
// build the sum of 16bit words
	while(len>1)
	{
		sum += 0xFFFF & (*rxtx_buffer<<8|*(rxtx_buffer+1));
		rxtx_buffer+=2;
		len-=2;
	}


ถ้ายังมีข้อมูลเหลืออีก 1-byte ให้เพิ่ม low byte เข้าไป ค่าใน low byte จะเป็น 0x00 แล้วนำข้อมูลที่เหลือไปคำนวณค่า checksum ต่อ.

Code:
// if there is a byte left then add it (padded with zero)
	if (len)
	{
		sum += (0xFF & *rxtx_buffer)<<8;
	}


ถ้าค่า checksum ที่ได้มีความยาวมากกว่า 16-bits ให้นำ 16-bits บน ( 16..31 ) มาบวกกับ 16-bits ล่างอีกที ทำแบบนี้จนกว่าผลลัพธ์ที่ได้เหลือเพียง 16-bits.

Code:
// now calculate the sum over the bytes in the sum
	// until the result is only 16bit long
	while (sum>>16)
	{
		sum = (sum & 0xFFFF)+(sum >> 16);
	}


นำค่า checksum ที่ได้มาทำ 1's complement แล้วส่งค่า checksum กลับไป

Code:
// build 1's complement:
	return( (WORD) sum ^ 0xFFFF);


    ค่า checksum ของโปรโตคอล IP คือข้อมูลขนาด 16-bits ที่ได้จากการทำ 1's complement ของการบวกข้อมูลแบบ 16-bits ก่อนที่จะคำนวณค่า checksum ทุกครั้ง ในช่อง checksum จะต้องเป็นศูนย์ ก่อนเสมอ, ข้อมูลที่นำมาคำนวณจะเริ่มจาก address แรกของ IP Header (0x0E) ไปจนถึง address สุดท้ายของ IP Header (0x21) ดังรูปตัวอย่าง.

Code:
ตัวอย่างการคำนวณค่า checksum ของ IP Header.


45 00 + 00 34 = 4534 + 48 18 = 8d4c + 40 00 = cd4c + 40 06 = 10d52 + 00 00 = 10d52 + 0a 01 = 11753 + 01 4c = 1189f + 0a 01 = 122a0 + 01 01 = 123a1 23a1 + 0001 = 23a2 นำ 23a2 มาทำ 1's complement = dc5d



รูปตัวอย่างของ IP checksum


    ค่า checksum ของโปรโตคอล ICMP เป็นค่าผลรวมแบบ 16-bits ของข้อมูลที่เป็น header และ data ของโปรโตคอล ICMP ข้อมูลที่นำมาคำนวณจะเริ่มจาก address แรกของ header (0x22) ไปจนถึง address สุดท้ายของข้อมูล (ในรูปตัวอย่างคือ 0x49) และก่อนที่จะคำนวณค่า checksum ในช่อง checksum จะต้องเป็น 0 ก่อนเสมอ


รูปตัวอย่างของ ICMP checksum


    ค่า checksum ของโปรโตคอล TCP เป็นค่าผลรวมแบบ 16-bits ของข้อมูลที่เป็น header และ data ของโปรโตคอล TCP ข้อมูลที่นำมาคำนวณจะเริ่มจาก address แรกของ Source IP address (อยู่ใน IP Header ) ไปจนถึง address สุดท้ายของข้อมูล (TCP data) โดยค่าที่นำมาคำนวณรวมกับ Header, data ของ TCP ก็จะมีดังรูป



    ซึ่งค่า Protocol กับความยาวของ TCP นี้จะนำมาบวกกันแล้วส่งให้ฟังก์ชั่นผ่านตัวแปล DWORD sum ตัวอย่าง IP_PROTO_TCP_V + sizeof(TCP_HEADER) + dlength ในที่นี้ ค่า Protocol ก็คือ IP_PROTO_TCP_V (อยู่ใน ip.h) ค่าความยาวของ TCP ก็คือ sizeof(TCP_HEADER) + dlength (dlength คือความยาวของ TCP data) และก่อนคำนวณค่า checksum ทุกครั้ง ในช่อง TCP checksum จะต้องเป็น 0 เสมอ


รูปตัวอย่างของ TCP checksum


    ค่า checksum ของโปรโตคอล UDP เป็นค่า 16-bits ที่ได้จากการบวกแบบสิบหกบิทของข้อมูลแล้วนำมาทำ 1's complement โดยเริ่มจากตำแหน่ง Source IP address ใน IP Header ไปจนถึง Address สุดท้ายของ UDP data โดยที่ก่อนที่จะคำนวณค่า checksum จะต้องทำให้ค่า checksum เก่าเป็นศูนย์ก่อน และค่าที่นำมาคำนวณค่า checksum ด้วยก็คือ Protocol, Total length โดยค่าทั้งสองจะเอามาบวกกันแล้วส่งค่านี้ไปให้ฟังก์ชั่นผ่านตัวแปล DWORD sum





ตัวอย่างค่า UDP checksum


Contact : MSN :