UDP checksum

HackForum

UDP checksum#
Nemá někdo funkční příklad funkce, počítající UDP checksum?


unsigned short in_cksum(unsigned short *addr, int len)
{
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;

while (nleft > 1) {
sum += *w++;
nleft -= 2;
}

if (nleft == 1) {
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}

sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);

answer = ~sum;
return (answer);
}

toto je fungující (ověřeno na IP hlavičkách a ICMP protokolu) funkce počítající checksum. UDP checksum se počítá s pseudo-hlavičky + z UDP hlavičky + z dat. Pseudo-hlavička se zkládá ze zdrojové adresy (4B), z cílové adresy (4B), 1B je "dorovnávací", protokol (1B), delka UDP(2B).

Proto by měla fungovat tato funkce, opsaná z [link]


struct psd_udp {
struct in_addr src;
struct in_addr dst;
unsigned char pad;
unsigned char proto;
unsigned short udp_len;
struct udphdr udp;
};

unsigned short in_cksum_udp(int src, int dst, unsigned short *addr, int len)
{
struct psd_udp buf;

memset(&buf, 0, sizeof(buf));
buf.src.s_addr = src;
buf.dst.s_addr = dst;
buf.pad = 0;
buf.proto = IPPROTO_UDP;
buf.udp_len = htons(len);
memcpy(&(buf.udp), addr, len);
return in_cksum((unsigned short *)&buf, 12 + len);
}


ale z nějakého mně neznámého důvodu je checksum vždycky špatný... i když si z té stránky ten příklad zkopíruju, zkompiluju a spustím, vždycky odešle paket s špatným UDP checksumem.

Takže kdyby měl někdo po ruce kod s funkční funkcí na počítání UDP checksumů, byl bych moc vděčný za postnutí, já pořád nemůžu najít důvod, proč mi to počítá checksum špatně.

----------
Get enlightened!
(odpovědět)
mr.Crow | E-mail | Website5.7.2008 15:02
re: UDP checksum#
kdyby to někoho zajímalo, odpozoroval jsem, že se mi v druhém byte checksumu liší můj vypočítaný (špatný) od správného vždycky o 0x20, takže řádek

return in_cksum((unsigned short *)&buf, sizeof(struct psd_udp));

jsem jednodušše vyměnil za:

return in_cksum((unsigned short *)&buf, sizeof(struct psd_udp)) - htons(0x20);

a funguje to. Teď jen přijít na to, kde je chyba, protože tohle asi nemusí fungovat vždycky...

----------
Get enlightened!
(odpovědět)
mr.Crow | E-mail | Website6.7.2008 11:55
re: UDP checksum#
tak jsem si to pod dlouhé době vyřešil sám, chyba není ve výpočtu checksumu, chyba je v tom příkladu, kde se vytváří IP datagram o velikosti 60B, ale vytvoří se jen IP hlavička (velikost IP datagramu je v ní nastavena na 60B) a UDP hlavička, což je 28B - a pouze z těchto 28B se počítá checksum.

----------
Get enlightened!
(odpovědět)
mr.Crow | E-mail | Website6.7.2008 12:34
re: UDP checksum#
chlape, chlape, co ten kod? To je humus...
(odpovědět)
_( | )_ | 85.132.197.*6.7.2008 12:49
re: UDP checksum#
vždyť to já nepsal, to je funkce z toho webu ;) ale jestli k tomu kodu máš nějaké konkrétní připomínky, rád si je vyslechnu, ať vím, jak se psát nemá...

----------
Get enlightened!
(odpovědět)
mr.Crow | E-mail | Website6.7.2008 12:58
re: UDP checksum#
Akurát se mi tam nepozdává ta konstanta 12, nebylo by lepší tam propašovat &buf.udp-&buf.src?
(odpovědět)
gugumaa | 85.160.17.*7.7.2008 11:13
re: UDP checksum#
gugumaa: stačí místo (len + 12) zapsat sizeof(struct psd_udp), len je totiž velikost udp hlavičky (struct udphdr), 12 má být velikost toho zbytku struktury psd_udp .... nevím proč to ten člověk zapsal s dvanáctkou, podle jeho CV to vypadá, že je to někdo, kdo se vyzná....

ta funkce se stejně ale musí trochu přepsat, protože nepočítá s daty, které bych chtěl v udp datagramu přenášet, takže je to jedno :-)

----------
Get enlightened!
(odpovědět)
mr.Crow | E-mail | Website7.7.2008 11:27
re: UDP checksum#
sizeof ještě lepší, máš bod.
(odpovědět)
gugumaa | 85.160.17.*7.7.2008 14:21

Zpět
 
 
 

 
BBCode