mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Der Ethernet Thread


Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Ich dachte mir, da ich sicherlich nicht ganz der einzige da draussen
bin, der gerade an einer udp/tcp etc unterstützung schreibt, starte ich
diesen Thread. Er soll dazu dienen allgemein Fragen zu dem Thema zu
sammeln, um denen, die sich später um die Suche bemühen, die Arbeit zu
erleichtern. - Ethernet auf dem uC scheint ja immer mehr im kommen zu
sein, mca25 webcam, uli's webserver etc :-)

Vielleicht gibts sonst ja auch niemanden der eine Frage hat, was ich
aber bezweifle...
Also starte ich mal:

Bis anhin habe ich ARP und udp empfang erfolgreich implementiert,
klappt wunderbar, nur; bei den Replies habe ich Probleme, um genau zu
sein mit den CRC16 Checksummen beispielsweise für ICMP.(Meine Ping
Antworten kommen zwar an, allerdings sind sie ungültig, wegen einer
falschen Checksum.) Irgendwie finde ich es sinnlos ein buch über die
Materie zu kaufen, da ich mir das restliche Wissen mit einigen
Ausnahmen eigentlich gut über Ethereal aneignen kann. Die Frage
bezüglich CRC ist nun eigentlich eher - was für einen Initial wert
brauche ich jeweils..(?) und für welchen Bereich des Packets muss man
z.B. gerade bei ICMP die CRC anwenden, nur die Daten oder für den
ganzen icmp-'Abschnitt'...Fragen über Fragen ich weiss, aber am Ende
möchte ich von der Sache eigentlich eine Ahnung haben und nicht nur
Codes von anderen Leuten kopieren, dabei lernt man schliesslich nicht
so viel...

Mfg, Nik

Autor: Ssss Ssssss (sssssss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Zum Thema IP/TCP/UDP gibts bei wikipedia einiges. Sonst google & co.

Zum Thema ICMP checksum mal ein auszug aus meinem avrETH1 projekt:
    //"calculate" checksum:
    //use quick & dirty hack, we change only the icmp type
    //so we cant calculate the new checksum like this:
    if (buffer[ICMP_POS_CHECKSUM+0] > 0xFF-0x08)
      buffer[ICMP_POS_CHECKSUM+1] = buffer[ICMP_POS_CHECKSUM+1] + 1;

    buffer[ICMP_POS_CHECKSUM+0] = buffer[ICMP_POS_CHECKSUM+0] + 0x08;

Ich nehme dazu einfach das Alte Paket und änder nur den Typ von
ICMP_TYPE_ECHO_REQUEST nach ICMP_TYPE_ECHO_REPLY.
Und das verändert die checksum nur minimal (siehe oben) 8)
Ist schön schnell und braucht wenig program space 8)

Bei udp/tcp mache ich es aber anders, da baue ich alle Pakete komplett
selber zusammen
(ohne die alten zu recyclen)

Bye, Simon

Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohe danke :-) Ich habe eben grundsätzlich noch Problem mit dem
Verständniss von CRC, was sich ändern wenn ich dieses und jenes Byte
ändere(wie z.B. das Type byte..)

Ich versuche das gerne mal einzubaun, Udp replies brauche ich im Moment
sowiso noch nicht.. :-P

Nik


P.S. müsste es in deinem Kommentar nicht can heissen? :-X

Autor: Daniel Nöthen (bip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Nik, schaumal in die RFC 792:
http://www.faqs.org/rfcs/rfc792.html
Dort ist das ganze Protokoll definiert.
Unter Checksum findet man folgendes:

"The checksum is the 16-bit ones's complement of the one's
complement sum of the ICMP message starting with the ICMP Type.
For computing the checksum , the checksum field should be zero."

Vielleicht hiflt dir das ja weiter. Ich verstehs leider nicht so
wirklich :(
Kann das hier vielleicht jemand anhand eines Beispiels erläutern? Wäre
nett :)

Gruß,
Daniel

Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es läuft!! Danke Simon ;-) laut etheral 1.3ms ping über einen Switch
:-)))


@Daniel Danke für den Link, ich werd mich dort dann auch mal nach TCP
umschauen, scheint ja ziemlich viel zu geben dort :P
Den Satz über die Checksum checke ich auch nicht wirklich irgendwie
braucht man alle 16 bit des Headers um die Start Crc zu berechnen.
Allerdings gibts im icmp header ja nur 2 Were die 16bit lang sind..(?)

Autor: André Kronfeldt (freakazoid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Den Satz über die Checksum checke ich auch nicht wirklich irgendwie
> braucht man alle 16 bit des Headers um die Start Crc zu berechnen.
> Allerdings gibts im icmp header ja nur 2 Were die 16bit lang
sind..(?)
Vergiß die Organisation der Datenfelder. Nimm einfach 16Bit-Blöcke,
addier die und bilde das Einerkomplement. Sollte die Bytezahl ungerade
sein, nimm das letzte Byte als HIGH und 0x00 als LOW vom letzten Wort
(16-Bit-Wert).

Grüße,
André

P.S.:
Das ist CRC16? Glaub ich nicht. Da is weder XOR, noch sonstwas drin.
Nach meiner Kenne nimmt man aber einfache Addition um die Neuberechnung
 der Checksumme in den Nodes (Switch, Router, ...) einfach zu halten.
Neuberechnung ist nötig, da TTL dekrementiert wird.

Autor: André Kronfeldt (freakazoid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BTW: Wenn ich permanent Pakete (z.B. Ping-Replys) vom ENC28J60 sende,
kommen die zwar am Switch an (LED blinkt), aber ein Rechner weiter
fällt  ca. jedes 5.-8. Paket weg.
Das Abort-Flag im ENC ist NICHT gesetzt,
TX-Logik wird gemäß Errata resettet,
Fullduplex/Halfduplex macht keinen Unterschied.

Kann das jemand nachvollziehen, oder ist meine Schirmung nur Mist?

Grüße, Freakazoid

Autor: Ssss Ssssss (sssssss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
crc:
nee das is kein crc, wird einfach nur aufaddiert und dann nochmal
invertiert glaub ich.

Hmm sowas hatte ich nie. Auch aufm Steckbrett nicht. Selbst nen
floodping geht ohne Probleme ;)

Oder was meinst du mit permanent senden ? Nur raushauen ohne ein
eingehendes Paket ? Das hab ich noch nie getestet.

Alle Cs dran ? (der dicke elko + alle 100nF ?)

Bye, Simon

Autor: André Kronfeldt (freakazoid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon:

>Alle Cs dran ? (der dicke elko + alle 100nF ?)
Ja. Ich bin ja lernfähig ;-)

Ich hab als Test mal nur Replys zurückgesendet. Ohne Requests ;-)
Haben zwar keinen Sinn, tauchen aber in TCPdump/Packetyzer auf.

ping -f -c 1000 192.168.0.234
PING 192.168.0.234 (192.168.0.234) 56(84) bytes of data.
........................................................................ 
.............................
--- 192.168.0.234 ping statistics ---
1000 packets transmitted, 899 received, 10% packet loss, time 3474ms
rtt min/avg/max/mdev = 1.464/1.545/5.265/0.145 ms, ipg/ewma 3.477/1.550
ms

Komisch ist aber, daß die Flags im ENc alle auf 'OK' stehen.

Ws hast Du aus dem Errata umgesetzt?

Grüße, Freakazoid

Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okay ja ich bin einfach mal davon ausgegangen dass es crc ist...werds
dann mal versuchen(btw:bezieht sich das nun nur auf ICMP oder allgemein
auch auf tcp udp usw?)


@freak
das es an der Hardware liegt glaube ich weniger, ich hab hier auch mal
nen floodping ausprobiert, klappt tadellos 100 mal ohne ein verlorenes
Packet ... schau dir mal meine "Schirmung" an .. ;)

http://sharespace.nikbamert.com/files/DSCN5130_small.jpg

Evt. liegts am Switch, ich hab hier mit meinem Teilweise auch
Probleme,
vorallem wenn ich mein avr system einschalte, dauerts ein weilchen, bis
der Switch wirklich 'begriffen' hat, dass da was dran ist(ich meine
nicht die Link led!), denn teilweise kann ich bis eine Minute warten,
bis ich dann Packete senden kann, manchmal gehts aber auch ganz
schnell..

Nik

Autor: André Kronfeldt (freakazoid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thanx.

@Simon: Hast Du den Kleinen direkt am Rechner, oder über einen Switch?
Wenn ich aber ein Floodping im Heim-Netzwerk an einen anderen Rechner
über diesen Switch mache kommt alles an. Naja. Vielleicht liegt es doch
an der einzigsten 10MBit-Node im Netz. Die ist halt einsam ;-)

Autor: Ssss Ssssss (sssssss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>das es an der Hardware liegt glaube ich weniger, ich hab hier auch mal
>nen floodping ausprobiert, klappt tadellos 100 mal ohne ein
verlorenes
>Packet ... schau dir mal meine "Schirmung" an .. ;)
Meine Schirmung:
http://www.mikrocontroller.net/attachment.php/3297...
;D ;D ;D

>dauerts ein weilchen, bis der Switch wirklich 'begriffen' hat, dass
da was dran ist
Manchmal erkennt mein switch den enc beim einschalten auch nciht bei
mir.
Ca alle 50x starten empfängt der enc keine Pakete vom switch.
Kurz power weg und dran und schon gehts wieder.

Erratas:
Ich glaub da hab ich fast keine implementiert...
- reset mache ich per reset pin und 10ms warten (min 1ms)
- vorm paket senden resette ich die tx logic (set&clear
ENC28J60_BIT_TXRST)
- neue pakete erkenne ich an PKTIF, das im errata vorgeschlagene lesen
von ENC28J60_REG_EPKTCNT funzt irgendwie nicht
- pakete hole ich per polling ab (nutze die interrupts nciht)
- ungerade/gerade prüfen des lese(?) pointers mache ich auch nicht

Bye, SImon

Autor: Ssss Ssssss (sssssss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
geht über nen switch. sonst sind auch nur 100mbit kisten dran.

Autor: André Kronfeldt (freakazoid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> neue pakete erkenne ich an PKTIF, das im errata vorgeschlagene lesen
> von ENC28J60_REG_EPKTCNT funzt irgendwie nicht
Bei mir funzt beides. ENC28J60_REG_EPKTCNT hat halt den Vorteil das man
die Anzahl kennt. Dauert aber auch länger (Bankswitch vorher). Rev2 und
Rev4 verhalten sich übrigens gleich.

Das Resetten der Logik wirkt sich bei mir nich aus. Aber weils drin
steht, mach ich es halt.

Die 1ms warte ich nicht nach dem Reset. der Fehler tritt aber auch
nicht direkt danach aus, sondern mitten im Betrieb. Allerdings hab ich
festgestellt, daß weniger Pakete wegfallen je schneller das
'drumherum' ist (ASM, kein Debug, ...). Egal ich krieg den noch
klein.

Autor: Ssss Ssssss (sssssss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
EPKTCNT liefert bei mir manchmal "neues paket" obwohl nix neues da
ist.
PKTIF funktioniert bestens (bei rev2 und rev4 :-\)

Bye, Simon

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Addition im Einerkomplement ist heute einigermassen ungebräuchlich,
eigentlich nur dank TCP/IP nicht gänzlich ausgestorben. Das war aber
früher garnicht so selten, nicht zuletzt weil Seymour Cray einen Narren
daran gefressen hatte.

Es bedeutet, dass ein oben rauslaufender Übertrag unten gleich wieder
reingerechnet wird.

In diesem Fall bedeutet es, dass der Block 16bit-weise mit Übertrag
addiert wird, also ungefähr so:
     clear carry
     clear accu
     add-with-carry accu, word0
     add-with-carry accu, word1
     add-with-carry accu, word2
     ...
     add-with-carry accu, wordN
Das hat ein paar hübsche Eigenschaften, die auch die Implementierung
erleichtern/beschleunigen. Dazu kann ich das entsprechende RFC-Dokument
von TCP/IP empfehlen.

Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab noch etwas neues festgestellt. Teilweise 'erkennt' mein Switch
ja das Teil nicht - dachte ich. Nun liegts aber denke ich trozdem am
avr. Wenn ich zB bei jedem ICMP packet noch aufm Display ausgebe, dass
eines angekommen ist, dann klappt es anstandslos, jedesmal wenn ich die
schaltung am switch einschalte. Lasse ich diese 'debugausgabe' weg,
dann gehts teilweise, aber nicht immer...sehr merkwürdig - die spi
geschwindigkeit bleibt ja dieselbe..

Autor: Robert Weber (rweber)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
- Schon mal die ARP-Table auf beiden Seiten überprüft?
- Nimmt Du immer die selbe MAC adresse?

Autor: Gironymo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

find ich ja sehr interessant was ihr da so schreibt. Mir gehts
eigentlich genau so wie Nik, nur mit dem Unterschied, dass ich noch
keine Schaltung hab. Hat von euch vielleicht jemand einen Schaltplan
für mich, vielleicht sogar mit einer kurzen Doku (ich möcht dabei auch
was über Elektronik lernen ;o)?

Besten Dank

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habt ihr euch schon mal mit FreeRTOS.org auseinander gesetzt?
Dort gibt es mehrere Ports mit Webserver die ethernet drin haben.
Ursprünglich wurde dieses von einem Rowley Mitarbeiter geschrieben.
Ist auf ROwley.co.uk zu finden. vll einfach als Anschauungsmaterial

Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, also ich bins wieder einmal :-)

@Robert Weber

Ja, ich hab immer dieselbe Mac Adresse, wenns dann nicht klappt sieht
das etwa so aus...Mein Pc schickt ein Broadcast Packet, welches nach
meiner mac fragt, allerdings gibt's keine Antwort von meinem Server.
Die Software ist allerdings wasserdicht, bzw. wenns dann einmal läuft,
dann läufts stundenlang durch, ich glaube nicht das es an meiner
Software liegt..:( Aber mittlerweile klappts auch öfter, weshalb weiss
ich allerdings nicht.

@ChecksumExperten
So ich hab nun mal versucht mit Hilfe von Ulrich's Stack und dessen
Checksum Funktion das Ganze zu verstehen. Verstanden habe ich's soweit
einmal..denke ich. Nur klappts nicht wirklich.

Also ich sende ein UDP Packet mit folgenden Daten:
Sourceport 85  (0x0055)
Dest. port 1113(0x0459)
Länge      13  (0x000D)
Data       Atest (0x4174,0x6573,0x74) (schon in die besagten 16 bit
Blöcke aufgeteilt)

Dann addiere ich das ganze und bekomme 0xac16, einmal ~ drüber und dann
habe ich 0x48f6. Dies ist laut Ethereal aber falsch, rauskommen sollte
0x5c11. Die Variable in der ich das alles aufaddiere ist vom typ
uint16_t. Einen Übertrag gibts bei den paar wenigen bytes soweit ich
sehe noch gar nicht, deshalb sehe ich nicht ganz, was ich denn falsch
mache..Ich hab auch schon zig Varianten versucht(ohne ports, ohne
lenght field etc...) Vielleicht kann mir jemand sagen was ich da noch
nicht ganz verstanden habe :-)...

Grüsse & ein Frohes Osterfest,

Nik

Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha..Tcp und Udp scheinen einen 'Pseudoheader' zu haben, wohl eine
Erfindung um die Programmierer zu nerven :P

Autor: Nik Bamert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich mach mich dann mal an die Arbeit, juhuuu :P, gefunden hab ich das
übrigens hier : http://www.netfor2.com/contents.htm

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.