User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Pascal and Delphi section within the Software Development category of DaniWeb, a massive community of 425,793 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,122 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Pascal and Delphi advertiser: Programming Forums

C++ to Delphi CheckSum code

Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,876
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 11
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: C++ to Delphi CheckSum code

  #2  
May 16th, 2008
That C code is a mess. And it is dangerous because it uses bitfields (which C++ does not guarantee to be packed in any specific order -- so results vary by compiler!).

Alas, why don't programmers stp usng stpd shrt nonsns nms.

Anyway:
  1. uses
  2. SysUtils, // for PByteArray
  3. Winsock; // for htons()
  4.  
  5. const
  6. IP_DF = $4000; // don't fragment flag
  7. IP_MF = $2000; // more fragments flag
  8.  
  9. type
  10. in_addr = record ... end; // you must fill this in
  11.  
  12. iphdr_ptr = ^iphdr;
  13. iphdr = packed record
  14. ip_hl__ip_v: byte; // header length, version: four bits each
  15. ip_tos: byte; // type of service
  16. ip_len: shortint; // total length
  17. ip_id: word; // identification
  18. ip_off: shortint; // fragment offset field
  19. ip_ttl: byte; // time to live
  20. ip_p: byte; // protocol
  21. ip_sum: word; // checksum
  22. ip_src: in_addr; // source address
  23. ip_dst: in_addr // destination address
  24. end;
  25.  
  26. procedure RecalculateIPChecksum( pIpHeader: iphdr_ptr );
  27. var
  28. sum: longword;
  29. i: longword;
  30. buff: PByteArray; // see note 1
  31. begin
  32. sum := 0;
  33. i := 0;
  34.  
  35. // Initialize checksum to zero
  36. pIpHeader^.ip_sum := 0;
  37. buff := pIpHeader;
  38.  
  39. // Calculate IP header checksum
  40. while i < (pIpHeader^.ip_hl__ip_v and $F) *sizeof( longword ) do // see note 2
  41. begin
  42. inc( sum, (buff[ i ] shl 8) +buff[ i +1 ] );
  43. inc( i, 2 )
  44. end;
  45.  
  46. // Keep only the last 16 bits of the 32 bit calculated sum and add the carries
  47. while (sum shr 16) <> 0 do
  48. sum := (sum and $FFFF) +(sum shr 16);
  49.  
  50. // Take the one's complement of sum
  51. sum := sum xor $FFFFFFFF;
  52.  
  53. // ...and store it in network order
  54. pIpHeader^.ip_sum := htons( sum )
  55. end;

The above code presumes the following:
  1. typedef unsigned char* PUCHAR;
  2. bitfields are packed in MS VC++ order [1], meaning that ip_hl is in the lower four bits and ip_v is in the upper four bits. If this is not the case you will need to change that and $F to shr 4.

Enjoy!
Last edited by Duoas : May 16th, 2008 at 10:19 am.
Reply With Quote  
All times are GMT -4. The time now is 3:22 pm.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC