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
Hi! Zum Thema IP/TCP/UDP gibts bei wikipedia einiges. Sonst google & co. Zum Thema ICMP checksum mal ein auszug aus meinem avrETH1 projekt:
1 | //"calculate" checksum:
|
2 | //use quick & dirty hack, we change only the icmp type
|
3 | //so we cant calculate the new checksum like this:
|
4 | if (buffer[ICMP_POS_CHECKSUM+0] > 0xFF-0x08) |
5 | buffer[ICMP_POS_CHECKSUM+1] = buffer[ICMP_POS_CHECKSUM+1] + 1; |
6 | |
7 | 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
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
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
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..(?)
> 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.
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
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
@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
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
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 ;-)
>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/329781/avrETH_steckbrett_p4023794.jpg ;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
> 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.
EPKTCNT liefert bei mir manchmal "neues paket" obwohl nix neues da ist. PKTIF funktioniert bestens (bei rev2 und rev4 :-\) Bye, Simon
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.
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..
- Schon mal die ARP-Table auf beiden Seiten überprüft? - Nimmt Du immer die selbe MAC adresse?
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
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
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
Aha..Tcp und Udp scheinen einen 'Pseudoheader' zu haben, wohl eine Erfindung um die Programmierer zu nerven :P
Ich mach mich dann mal an die Arbeit, juhuuu :P, gefunden hab ich das übrigens hier : http://www.netfor2.com/contents.htm
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.