Giter VIP home page Giter VIP logo

Comments (49)

georgp24 avatar georgp24 commented on June 3, 2024

Can we implement it this way: I pass an ip address to the ne2k driver and that handles ARP then?

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

The Ethernet driver is not supposed to have any knowledge of the higher level protocols encapsulated in the Ethernet frames, as the serial driver does not know what protocol is used on the serial line (VT52, SLIP, etc). Its role is only to send and receive raw packets.

On other systems, that role is exposed to user space with a socket with AF_PACKET and SOCK_RAW attributes.

Moreover, ARP is a part of the IPv4 protocol suite, and is tightly coupled to IP. IP should direct ARP on the right subnet (so the right device), and IP knows the local addresses that could be responded to ARP.

For that reason, best place to implement ARP is ktcp, not the driver.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I opened the /dev/eth driver with ktcp but I did not receive any packets. The select works with the new version of select.c but reports no data available. I would need to see the ARP requests to be able to respond.

When ip.c receives a ping it will call icmp.c and that sends a response packet for the ping. One could add that a new program arp.c will be called when an ARP request is received. This builds and sends the ARP reply if the request is for the "right" ip address.

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

To get incoming ARP request, follow the steps in #18 to cause QEMU to send that ARP request to the guest.

ktcp should not only respond to incoming ARP request, but also send that request as a client to find which MAC should be used for a given remote IP address, and should maintain a local IP <-> MAC table to avoid repeating that request.

As ARP is at the same level as IP, ktcp should first get the packet from the driver, look at the packet header, and then forward either to the IP layer or to the ARP layer. ICMP is wrapped into IP, one level higher than ARP.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I implemented ARP so far that I can properly send an ARP Reply and get TCP/IP packets following that. However, the "read" instruction always returns a length of 64. This is too short for TCP/IP, I can see no data, just part of the header.

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Please push your commits on the ne2k branch to make your latest changes visible, so that I can have a look at them, and try to figure out what is going wrong here.

Please also rebase your ne2k branch on upstream master, and avoid mixing bug fixes, improvements or enhancements in the same branch in general. Otherwise it is difficult for other contributors to "cherry pick", or to get back your changes in their context.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I can push the code but I have to run through the programs first to see what junk has to be removed before posting.

This is what I observed. I do the following read:
#define BUFFER_SIZE 2048
len = read(devfd, &sbuf, BUFFER_SIZE);

However, at ne2k_main.c in static size_t eth_read()
the requested length (len) which is passed to thei function is always 64 bytes. But the received packet has a size of 1792 bytes. So, as the comment says, (1792-64) are lost since I cannot repeat the read call.

Any ideas? Seems ELKS limits the read to 64bytes.

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

If you don't push your commits in your repository, I cannot see the code and so cannot help.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Finally managed to push the code. However, the rebase command did not allow me to push since the remote and the local branches became different. So I got pretty entangled.

The commit is "Add working ARP reply."

I now made a new branch ne2k-2 which is rebased on the latest elks/master

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Wireshark shows that everything works fine: after ARP request + reply, QEMU sends a TCP SYN packet as the first step of connexion, then repeats continuously that packet as it gets no response from ktcp.

But as this TCP packet is less than 64 bytes (actually 58), as for ARP packet, it is padded up to the minimum Ethernet frame size, that is 60 + 4 (CRC) = 64. So the Ethernet driver returns 64 to you for the ARP request, the TCP SYN, and the N x TCP retransmit.

You should not rely on the packet total size, but on the values in the IP / TCP headers. Play again !

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Marc-Francois,

I got ARP working and the host is sending now TCP/IP packets of 1792 bytes in size. As I outlined above, I always do a read for 2048 bytes in deveth.c and check how many bytes read returns. But the request for 2048 bytes is changed to 64 bytes when it arrives at ne2k_main.c in eth_read() . This is what I hoped you would look into.

Why is my read request for 2048 bytes converted to 64 bytes by ELKS?

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

It is not possible to have packet of 1792 bytes. The standard MTU for the Ethernet payload is 1500, and on NE2K, the maximum is 256 * 6 = 1536 - 4 CRC - 4 ring header = 1528 by packet.

It is also normal that the driver returns 64 bytes if the packet is 64 bytes, even if you requested 2048. That's the nature of a network driver, even if we implemented it as a character driver.

I already explained you why small packets are padded up to 64 bytes. Please use the QEMU option -net dump and look at the packets sent by the host. Nothing is going wrong here.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

OK, my test code did fool me with the 1792 bytes. And yes, I receive packets of 64 bytes.

When I get an ARP request I return an ARP reply and the host is following that with TCP/IP packets. Why is the host sending these empty packets and what does it expect from the ELKS system?

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

These are empty packets but with TCP port = 23 and flags = SYN. It means that the host is trying to establish a TCP stream connection to port 23, and the guest should reply with TCP flags = ACK.

This should be already implemented in ktcp, but I guess, as nobody in user space opened a socket AF_INET + SOCK_STREAM listening to port 23, ktcp ignores the connection request.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

E.g. ktcp does not have a link layer since it did not need that for slip. So I have to add that. Plus work my way through the code and see where it is stuck.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I enabled the link layer and my echo server is listening on port 23. So ELKS answers to the TCP/IP SYN packets now and this results in the following tcp/ip communication:
qemu-vlan0.pcap.zip

Can please you look at the file with Wireshark and tell me why the host is sending a reset after ELKS has sent an ACK answer to the SYN packet?

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

It is because the acknowledgement number in packet 4 is incorrect. The client (= the host initiating the connection) sent a SYN with sequence number = 0 in packet 3. It expected a reply from the server (= the guest that responds to the connection request) with acknowledgement number = 0 + 1 = 1. But the server sent 0.

So for the client, the server acknowledged a sequence number of 0 - 1 = 0xFFFFFFFF, meaning that the TCP connection was already established before (and for a long time with a so huge sequence number !), so it aborts immediately the current connection with RST.

Note : the sequence and acknowledgement numbers here are relative ones, as displayed by Wireshark. Actual numbers are absolute.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

When I look at the hex code, the sequence number field should be eight zeros I guess. Since it is 32 bit. From the ELKS code it seems that ELKS uses a time based number here. The field contains:
20 00 00 8F
Wonder why Wireshark reports a zero here. Same with the ACK number which is also not fully zeros.

I forced the code to put 00 00 00 01 into the field but Wireshark remained to report the field to be zero.

I guess it is late now, you were talking about the acknowledgement number, not the sequence number. But stil the hex code is not zero in this field.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Now I forced 00 00 00 01 into the acknowledgement number field. Wireshark tells me that this is an acknowledgement number of 4293943296. I am confused.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Ok, I now just added 1 to the acknowledgement number (which was not zero) and that satisfied the host. I will see why that has not been done be ELKS yet and proceed.

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Please read more carefully my posts:
Note : the sequence and acknowledgement numbers here are relative ones, as displayed by Wireshark. Actual numbers are absolute.

Wireshark displays relative numbers to ease the reading, starting from 0 for both numbers.

I can see that these numbers are already managed in tcp.c, so I don't understand why you need to force the numbering ?

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I usually read your posts carefully, but as I said it was late yesterday for me.

Yes, these numbers are managed by tcp.c but if I do not modify them the result will wrong as you write:

It is because the acknowledgement number in packet 4 is incorrect

Before analysing the code in detail to make a proper fix I wanted to see what difference the correct number would make, therefore I forced the numbering as a temporary test.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

When I tested SLIP I could not access the http server from the host. Therefore I currently think there may be a bug when tcp.c is in the listening state. As you found, the acknowledgement number produced by tcp.c is wrong.

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Mmm... not good to see that the current network stack could be buggy... let me ask the question to the mailing list, because I was expecting to get a working network stack just at the cost of adding the Ethernet capability, not at the cost of a long tuning of the whole.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Since I spent quite some time on the ktcp stack already I am not interested to replace it with a different one.

This stack has not been used for 15 years and you have to expect that bugs show up. ELKS itself contains quite a number of bugs which have not been found yet. Getting this stack to work properly with ethernet is not quickly done though.

But I expect to get this sequence number problem fixed during this week and then add ARP request and stack next weekend. Then you can also establish a connection from the ELKS side too.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I could solve the last problem, ntohl() did not work well with pointers and converted the one in the sequence number to zero. Now I get the following trace when I send a string of ones to the echo server on ELKS. Can you please tell me why the host is not satisfied with the response from ELKS?
qemu-vlan0.pcap.zip
Here is a second trace where I sent just a single "a":
qemu-vlan0-2.pcap.zip

OK, I advanced, forget about the traces above. Here is my latest trace. Please just comment on this one:

qemu-vlan0-4.pcap.zip

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

I like the "Marc-Francois" as telnet data :-)

In the latest *-4 sequence, everything works fine for ARP and TCP connection, but the guest faults on packet 7 with a wrong sequence number.

At packet 6, the host sends 15 bytes as telnet data, so it expects the guest to ACK with a relative sequence number of 1 + 15 = 16.

In packet 7, the guest ACK correctly with number 16.

But in the same packet 7, the guest incremented his own sequence number, despite it sent no data before, meaning for the host (and Wireshark), that a packet with data has been lost just before (and so the message "previous segment not captured").

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Puh, I got it working now. The problem was that bcc does not support shifting 32bit numbers by 24 bits. This made the macro in netorder.h fail. Therefore the htonl() and ntohl() macros failed and corrupted the sequence numbers.

Here is an example trace using my echo server and client: working-now.pcap.zip

Sorry for the name, but I am quite happy that it seems to work now :)

I have to remove the test codes first before I can commit my current version. I guess in the end I only needed to change two lines in the code. Sigh.

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Looks far better, nice job !

However, the sequence is incomplete: the graceful shutdown was initiated by the host (FIN + ACK), and acknowledged by the guest (ACK), but I guess you stopped the test before closing the socket on the guest, so one cannot see the end of the TCP connection shutdown (normally 4 TCP packets).

Another visible problem in Wireshark is a bad Ethernet frame in ARP response that I have to investigate, because I think it is linked to QEMU NE2K emulation, not the network layers on the guest.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I have the echo server running on ELKS and the echo client on the host. To terminate the client I enter CTRL-C, so this may be the reason that there is no normal shutdown sequence.

Since I programmed the ARP response I would at first look at my code. If you tell me what is wrong, I will try to modify the code.

I want to do a commit with my corrected netorder.h file and since you usually comment my commits I ask you in advance. I would like to rename it to inet.h and put it into elks/include/linuxmt. Then I would change all programs that use a local netorder.h to use the linuxmt/inet.h file. Including my not yet commit new version of echo server and client with additional af_inet support. Any comments to this?

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

I usually comment the pull requests from anybody, because it a good moment in Github workflow to make code reviews and to discuss the changes at the whole team level. But on ELKS, Jody is straightforward: either he trusts the pusher / likes the changes, and he merges before end of any discussion, or he does not trust / does not like, and he rejects.

Issues are also good places to discuss before any pull request, like we are doing these days, but he spends no time to manage them that way.

So my advice would be to limit the perimeter of your changes to ktcp, and to postpone modifications on other parts until we make a few iterations to stabilize the network layers and demonstrate to him that we could propagate the mature changes safely.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I have updated the netorder.h. file and find there are three or four basically identical netorder.h files in different directories in the ELKS code. Also I want to test the httpd application with the ktcp version I am working on and that also uses netorder.h.

So this commit is basically part of what I am currently working on.

It does not seem to take a long time to make this commit and so I will make that and see if it is accepted. If not I would not know how to proceed with ktcp though since I do not want to continue with a netorder.h file I know is faulty.

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

What do you mean by "make this commit" : pushing the commit from your local Git to Github to make it visible in the version tree, or requesting a pull to merge the commit into the main repository (so Jody's one) ?

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I think having a faulty and duplicated netorder.h file is no good in jody's master. So I will make a new branch based on the current master and make the proposed changes to that and ask for these to be pulled.

Then after that has been merged I can sync my ne2k-2 branch again and commit my current ktcp changes to that for you to download and test.

This is my plan.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I am stuck again. Now I have put the echoclient on the ELKS side and the echoserver on the host side. The server listens on 127.0.0.1:2323. The client sends to 10.0.2.2:2323.

I can send data from the client and receive an ACK for that but the echoserver reports no data and sends nothing back.

In Qemu I have -net user,hostfwd=tcp:127.0.0.1:2323-10.0.2.15:23 Do not know if this correct for this setup. Please find the current communication here:

client_on_elks.pcap.zip

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Could you make your current code visible through a commit push to your own repository (not a pull request), please, so that I can have a look ?

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I removed the host forwarding rule in the qemu.sh script and now I can connect from the echoclient on ELKS to the echoserver on the host!

Let me check my code for test printf's and stuff and then I will commit it to my own repository.

Georg

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I have posted a new version of ktcp modified for ne2k. This passes the following tests running Qemu:

  • run echoserver on ELKS and connect to that with an echoclient on the host. Send data back and forth.
  • run echoserver on the host and connect to that with an echoclient on ELKS. Send data back and forth.
  • download web page from google using urlget
  • slip still works, i.e. ping is working, did no further tests.

You have to run qemu with host forwarding if you connect from the host to ELKS. However, hostforwarding should not be specified if you want to connect from ELKS to the host.

For this I implemented ARP reply and request, a one entry ARP cache, routing to the gateway, reading the local mac with ioctl, adding the link layer, fix netorder.h and rename to arpa/inet.h.
Also got httpd to be installed in the /bin directory and have that loaded during boot. Made separate echoclient/echoserver code for internet and unix domain sockets in the test directory. Modified qemu.sh to support slip and http.

I will continue testing and see if I can make a readme file documenting how to use this.

Todo e.g.:

  • test httpd web server with ne2k and slip
  • test telnet from ELKS
  • the download of web page pauses in between the download
  • add name resolution
  • add dhcp support

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Looks very nice ! Let me play a bit with your branch to see it working...

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

The httpd daemon responds well, after adding /usr/lib/httpd in the rootfs template, so that the default index.html is correctly copied to the target.

Well, I think you reached a first milestone there, congratulations !

Please request the pull into Jody's master, to share this valuable contribution.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Thank you Marc-F.! I will write a readme file today how to test ktcp/ne2k and then make a pull request.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Marc-F.,

I do not want to make a single commit from this, but the "static" has to be removed in ip.h here:
char local_mac [6];

Otherwise it seems to have zero value when used in ip.c

Also the code is still using slip_mtu. This should be increased I think.

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Done for first point.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

Marc-F.,

maybe we should tell each other at what part of the networking code each of us is working to avoid duplication and conflicts.

Currently I try to implement querying a name server with tcp/ip. What are you working on?

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Yes, sure. For the Ethernet sub-project, I am testing and tuning ktcpand ne2k on a real network, so my next related commits would probably consist of improvements on the current code, no new features. I am focusing now on having an ARP cache with multiple entries (5 would be a good number).

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I have code for an ARP cache here. However, you need to init, search, delete, add functions to handle that. Also save the time to deprecate the entries after about five minutes. This is more code than I currently have in arp.c and therefore I did not include and test that yet to be able to come up with a working solution for networking quickly. And most of the time you will use the mac of the gateway anyway. So you end up with an arp cache of various internet addresses all having the mac of the gateway stored as their mac address.

from elks.

georgp24 avatar georgp24 commented on June 3, 2024

I have a question. I find the in_aton() function is used in many programs, e.g. ktcp.c or ttn.c. How can you avoid the duplication?

If I link the function to the kernel it is not found when linking the user programs even if I put it into a header file. Since the kernel code is not linked with ktcp.c it does not find the function.

There is also no library I could add the function in_aton() to which is linked by all network user space programs. Putting the function code into the header file is no good style. What would you suggest?

Georg

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

The right place is the dev86 libc library.

from elks.

mfld-fr avatar mfld-fr commented on June 3, 2024

Our first ARP implementation is roughly enough for a first milestone (except issue jbruchon#67), so I am closing this improvement task.

from elks.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.