[megoldva] TCP checksum hiba

 ( ScOut3R | 2009. június 13., szombat - 15:11 )

Sewastok!

C-ben probalok egy rem egyszeru tcp csomagot osszeallitani, azonban a tcp checksum kiszamitasaval gondjaim adodtak. Az interneten talalhato legtobb leiras szerint, ha 0-ra allitom ezt az erteket, akkor a kernel kiszamolja, azonban ez nem tortenik meg:


15:06:55.641479 IP (tos 0x0, ttl 255, id 31754, offset 0, flags [none], proto TCP (6), length 40) 127.0.0.1.34567 > 127.0.0.1.80: S, cksum 0x0000 (incorrect (-> 0xe521), 1164378112:1164378112(0) win 0

"Kezi" kiszamitas eseten viszont valahol hiba van a kodban, mert nem jo erteket kapok:


15:08:11.609891 IP (tos 0x0, ttl 255, id 31755, offset 0, flags [none], proto TCP (6), length 40) 127.0.0.1.34567 > 127.0.0.1.80: S, cksum 0xe634 (incorrect (-> 0xe521), 1164378112:1164378112(0) win 0

C tudasom meg igencsak gyerekcipoben jar, igy a kod nem egy profihoz melto, illetve sok reszt ( pl. a checksum-ot szamito fuggvenyt ) az internetrol, peldaprogramokbol vettem. A pastebinre feltett programnak, mint lathatjatok semmi gyarkolati haszna sincs, pusztan az en kivancsisagomat es tanulasi szandekomat fejezi ki. Ha valamelyikotoknek van egy kis ideje megnezne, hogy miert kapok rossz erteket a tcp checksum kiszamitasanal?
Nagyon koszonom!

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

lsb/msb problema nem lehet? a sima nativ c program, ha x86-on csinalod, az lsb-n tarolja a szamokat, a tcp csomag meg msb-t hasznal. a kododban az utolso felosszegzes is kicsit furcsanak tunik, nezd meg a wikipedian/rfc-ben hogy pontosan hogy is megy ez (annyria nem bonya, hogy ne lehessen atragni).

A.

Ha ez a gond, akkor a host kódolást kell hálózati kódolássá alakítani, ezt a Linux kernelben a hton[l|s] paranccsal lehet megtenni. Ez leellenőrzi az adott kódolást, így gonddal nem jár a kiadása, csak javíthat :)

--
Elder Scrolls

+1

illetve annyi, hogy az eredeti kodban, az int tipust lecserelnem short-ra (akkor igy a sok >> 16-nak sincs kvazi ertelme, ezert is meg kene nezni azt az rfc-t). es akkor igy nyugodtan lehet hasznalni a htons() es ntohs() fuggvenyeket, ahogy a kollega u'r is monda'.

A.

Koszonom az eddigi segitseget. Meg is probalom amit javasoltatok. Latszik, hogy autodidakta modon alltam neki C-t tanulni, mert egyelore a bitmuveletek teljes sotetsegben vannak.

Jo ez igy, ugy elvesztened a carry-t.
==
`Have some wine,' the March Hare said in an encouraging tone.
Alice looked all round the table, but there was nothing on it but tea.

Ez a kód biztosan jó, címek legyenek network byte orderben, a len host byte orderben, a buffer as-is, akkor az eredmény is network byte orderben lesz.

#define PROTO_TCP (6)

static u16_t _checksum(const u32_t src, const u32_t dst, const char * _buf, int len) {
    u16_t * buf = (u16_t*)_buf; /* 16-bit one's complement */

    register u32_t sum = /* 32-bit accumulator */
        (src&0xFFFF)+(src>>16)+(dst&0xFFFF)+(dst>>16)+
        (PROTO_TCP<<8)+(u16_t)htons((u16_t)len); /* add pseudo header */

    for (;len>1;len -= 2) sum += *buf++; /* add the words of the tcp segment */

    if (len==1) sum += *(u8_t*)buf; /* if len is odd, add the remaining octet */

    while (sum>>16) sum = (sum&0xFFFF)+(sum>>16); /* add carry */

    return ~sum; /* returns the checksum */
}

--
The Net is indeed vast and infinite...
http://gablog.eu

Koszonom mindenkinek a segitseget! A problemam megoldodott. :)