mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UDP Prüfsumme bilden


Autor: SPI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Ich versuche zwischen einem PIC (16F877) an welchem ein ENC28j60 
angeschlossen ist, Daten an einen Computer zu senden. Soweit 
funktioniert auch alles, jedoch habe ich Probleme mit der Bildung der 
Prüfsumme.

Im Programm Wireshark entnehme ich eine Prüfsumme von 0xaef6.
Folgende Einstellungen stehen dabei im Internet Protocol:
    Version:4
    Header length: 20 bytes
    Differentiates services Field: (DSCP 0x00: Default; ECN: 0x00)
    Total Lenght: 94
    Identification: 0x0800 (2048)
    Fragment offset: 0
    Time to live: 128
    Protocol: UDP (17)
    Header checksum: 0xaef6
    Source: 192.168.1.31
    Destination: 192.168.1.41

Kann mir bitte jemand an diesem Beispiel erklären, welche Daten alles 
für die Prüfsumme benötigt werden und wie diese zusammengezählt werden, 
damit eine Prüfsumme von 0xaef6 herauskommt.


Herzlichen Dank
SPI

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: SPI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diesen Artikel habe ich auch schon gesehen, jedoch hat er nicht wirklich 
zur Lösung meines Problems beigeholfen.

Mfg

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da steht doch ganz genau drin, was alles verwurstet wird (und wie). Was 
ist denn noch unklar?

Autor: SPI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist nicht ganz bewusst welche Bytes zu einem Wort zusammengefügt 
werden.

Währen dies in meinem Beispiel:

             2 Bytes
Quelle:      192 168
               1 41
Ziel:        192 168
               1 31
Protokoll:   0x00 17
Länge UDP:   0x00 94


Wird demfall Time to live, Identification und Header length nicht für 
die Prüfsumme verwendet?

Danke für deine Hilfe!!!
Mfg

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Prüfsumme in deinem Wireshark-Beispiel ist die IP-Header-Checksum, 
nicht die UDP-Prüfsumme. In der englischen Wikipedia ist eigentlich 
ausreichend genau beschrieben, wie die berechnet wird, inklusive 
Beispiel (bei der Beschreibung zum Feld "Header Checksum"):

http://en.wikipedia.org/wiki/IPv4#Header

Die UDP-Prüfsumme beinhaltet auch den Payload, ist (bei IPv4) aber 
optional, muss also nicht unbedingt berechnet werden, sondern kann 
auch einfach auf 0 gesetzt werden.

Bei beiden Prüfsummen gilt, dass einfach die Bytes so wie sie über's 
Netzwerk gesendet werden in Zweiergruppen zu Words zusammengefasst 
werden (High-Byte zuerst).

Andreas

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zuallererst musst Du noch entscheiden - das hab ich vorhin vergessen.. - 
ob du die Prüfsumme im IP-Header berechnen willst (das scheint die zu 
sein, die Du oben zitiert hast) oder ob Du die Prüfsumme im UDP-Header 
(so stehts in der Überschrift und darauf bezieht sie auch obiger link) 
berechnen willst.

Für ersteres möchte ich hier ggf. noch [1] zur Lektüre nachliefern.

Die Berechnung als solches geschieht bei beiden weitgehend analog (der 
Teufel liegt wie immer im Detail..): Es werden immer 2 Bytes zu 
vorzeichenlosen 16-bit-Werten zusammengefasst und diese dann aufaddiert.
Welche Daten an welchen Stellen stehen steht in der 
Protokollspezifikation (z.B. in den genannten Links - am 
übersichtlichsten in den Bildern). Einfach immer hübsch Byte1/2 +Byte3/4 
+Byte5/6 usw. bis zum Ende.

HTH

[1] http://en.wikipedia.org/wiki/IPv4#Header

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens ist der ENC28J60 in der Lage, die Berechnung der 
IP-Header-Prüfsumme selbst durchzuführen. Du musst ihm nur verraten, von 
wo bis wo sich in seinem RAM der IP-Header befindet. Dann hättest Du das 
schonmal aus dem Kopf.

void
enc28j60_calcChecksum(uint16_t startAddr, uint16_t endAddr, uint16_t checksumAddr)
{
  uint16_t checksum;

  /* Set previous checksum to 0 */
  enc28j60_regWriteWord(EWRPT, TXBUFST + 1 + checksumAddr);
  enc28j60_bufWriteByte(0);
  enc28j60_bufWriteByte(0);

  /* Let ENC28J60 calculate the checksum for the specified range. */
  enc28j60_regWriteWord(EDMAST, TXBUFST + 1 + startAddr);
  enc28j60_regWriteWord(EDMAND, TXBUFST + 1 + endAddr);
  enc28j60_regSetBits(ECON1, DMAST | CSUMEN);
  while (enc28j60_regReadByte(ECON1) & DMAST);
  checksum = enc28j60_regReadWord(EDMACS);

  /* Store calculated checksum at "checksumAdr". */
  enc28j60_regWriteWord(EWRPT, TXBUFST + 1 + checksumAddr);
  enc28j60_bufWriteByte(checksum >> 8);
  enc28j60_bufWriteByte(checksum >> 0);
}

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobi schrieb:
> Übrigens ist der ENC28J60 in der Lage, die Berechnung der
> IP-Header-Prüfsumme selbst durchzuführen. Du musst ihm nur verraten, von
> wo bis wo sich in seinem RAM der IP-Header befindet. Dann hättest Du das
> schonmal aus dem Kopf.

Errata gelesen? Leider hat das Teil einen bösen Bug (unter DMA in den 
Errata), der Hardware-Checksumming mit dem Chip ziemlich unbenutzbar 
macht, zumindest dann wenn man nicht nur senden, sondern auch empfangen 
will.

Andreas

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Errata gelesen?

Um der Wahrheit die Ehre zu geben: Nein. Allerdings ist mir der Bug bis 
heute nicht aufgefallen. Den höheren Protokollschichten sei Dank :)

Autor: SPI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es nun endlich geschafft und die Checksummenbildung 
funktioniert sogar. Super!!

Herzlichen Dank für eure Hilfe.

Mfg SPI

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.