| 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) | |
|
|
| 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) | |
|
|
| 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) | |
|
|
| chlape, chlape, co ten kod? To je humus... (odpovědět) | _( | )_ | 85.132.197.* | 6.7.2008 12:49 |
|
|
|
| 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) | |
|
|
| 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 |
|
|
|
| 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) | |
|
|
| sizeof ještě lepší, máš bod. (odpovědět) | gugumaa | 85.160.17.* | 7.7.2008 14:21 |
|
|
|