VOGONS


PPP EtherDFS driver

Topic actions

First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've been working on adapting the lsppp driver for the EtherDFS protocol.

The orignal post is found here: Re: EtherDFS - a network drive for DOS

I'm continuing the information I discover on it (trying to get it running with my newly implemented EDFS PPP protocol routing from the client's connected Ethernet II drivers and programs to either another client running the same EDFSPPP driver or UniPCemu's packet server to run it through to real Ethernet) here.
One nice thing I've also added is functionality to perform a direct PPP connection with another device listening on the serial port (which is another copy of it's own driver, running in Hayes modem answer mode). So it can be dialed to to setup a 2-computer network of sorts. Although, it cannot handle PAP/CHAP when in answer mode (it isn't supported in it's source code), so it will force those disabled (not used) for the caller.

The call to DecodePacketByte at TSR.ASM (line 178) will receive the entire packet from the PPP datastream of the serial port.
After that, for some reason, it won't be parsed any more while the connect function is running for some reason?

It should reach 'ciend' with the packet fully queued.
From line 340 it will check if it's already dispatched. If not (it shouldn't usually), it reaches rcvlp, which enables interrupts during the dispatch, loads the length, protocol and buffer into cx, ax and si, calls the logging function and finally calls lcp_handler to make it handle the incoming packets.

So lcp_handler is where the whole incoming protocol packets etc. starts for when they're fully received and decoded. The code that executes doesn't seem to have any blocks, so incoming packets should be properly parsed.
The question of course is is the same counts for outgoing packets, which might be the issue. Or even more basic in this case: the raising of the open state of the EDFSCP layer (which might not actually be happening properly, seeing as the client doesn't seem to respond to the configure-requests from the packet server that's running on the other end (it's trying to open the EDFSCP layer when both incoming and outgoing connections are made). For some reason, the incoming connection (from server to client) is made, but outgoing isn't capable of being made, as the EDFSPPP client isn't reponding to the server's configure-req packets with a ACK/NAK/REJECT packet to make the connection, for some reason? The EDFSPPP client waits for the connection to come up (or a ESC keypress to force continue it, although not displayed on the screen). It mainly waits for the EDFSCP's layer to come up (through the LCP_handler function in LCP.ASM, which should eventually cause the state machine to trigger an ipcpup event once the connection is properly made). But for some reason, I see on the packet server that's connected that both ACKs have been made (the packet server's configure-request only gets ACKed/NAKed/REJected after the driver goes resident, not before the edfs-up.bat file is created, which is an issue, as it requires the EDFSCP layer to be properly up to get it's required information about the connected addresses to write to the file).

Edit: Yay! Managed to find the bug! It was a simple hexadecimal notation that was misinterpreted:
"or byte ptr [ipaddr_up],Ch".... When you remember that tasm actually interprets Ch not as hexadecimal 0xC, but as register CH (which is zero in this case!). So at best, an invalid number gets stored, at worst, the required operation (setting a flag that the layer has come up to serve the packets) does nothing (because the ch register (and CX for that matter) is zeroed in this case.

It's finally running now! 😁
Edit: Fixed a bug that was causing the CX register to be corrupted when returning from the sendparams function when sending a packet.
Edit: It's properly sending packets now, as I see UniPCemu's packet server receiving the packets and relaying them to the Ethernet II network without issues while sending.
Although I don't have any Ethersrv server ready to verify it's receiving functionality as well, that's for a later time to test.

The driver source code: https://bitbucket.org/superfury/etherdfs-ppp/

For now, the driver is working properly! 😁

Last edited by superfury on 2024-09-25, 13:02. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 10, by mateusz.viste

User metadata
Rank Member
Rank
Member

Sounds interesting but... can you tell in a few human words what it is for? Is it, like I assume, some contrived way to make EtherDFS talk to a server that is reachable over a phone line? If so, then why does it need to be EtherDFS-specific? Wouldn't it make sense to rather target a more generic Ethernet-over-modem solution?

http://mateusz.viste.fr | gopher://gopher.viste.fr

Reply 2 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++
mateusz.viste wrote on 2024-09-25, 06:43:

Sounds interesting but... can you tell in a few human words what it is for? Is it, like I assume, some contrived way to make EtherDFS talk to a server that is reachable over a phone line? If so, then why does it need to be EtherDFS-specific? Wouldn't it make sense to rather target a more generic Ethernet-over-modem solution?

The main issue with full Ethernet-over-modem would be that Ethernet II frames contain all kinds of packets, and afaik that cannot be directly reliably routed over PPP? Due to requirements of configuration etc.?
Or should I should adjust my server and client to send the whole Ethernet II frame as data (right now it checks the protocol for EDFS, then sets the PPP type according to that and puts the ethernet header (minus protocol) and all other data in the frame (the remainder of the data) after the addresses copy) over the PPP connection?
The main difference is that the protocol field is moved to the PPP header protocol, with all other data effectively staying in the same location (so DDDDDDSSSSSSPP* becomes PP(PPP frame header's final 2 bytes, although translated to/from a PPP-compatible ID, which is EF5h. The configuration is handled by protocol ID 8EF5h (since bit 8 cannot be set due to PPP protocol compression)) and followed by packet data DDDDDDSSSSSS*), in this case * being the EDFS packet. The receiver effectively reverts this, prepending DDDDDDSSSSSS (removing it from the packet data) and (that's followed by) EDF5h (when translated to little endian from it's packet format, as the protocol ID PP field) to create DDDDDDSSSSSSPP* to create the original packet that was sent.
So basically:
PPP Sender: DDDDDDSSSSSSPP* (ethernet II packet)->PP DDDDDDSSSSSS* (PPP-compatible)
PPP Receiver: PP DDDDDDSSSSSS* (PPP-compatible) -> DDDDDDSSSSSSPP*
The PP fields need to be translated due to PPP protocol and Ethernet II protocol being incompatible.

The main issue is that Ethernet II would need configuration, which has no official spec afaik? Not to mention stuff like IPCP, IPXCP etc. conflicting with it, due to mixing of packet addressing (headers and data parts being sent).

Last edited by superfury on 2024-09-25, 13:28. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 10, by mateusz.viste

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-09-25, 13:15:

The main issue with full Ethernet-over-modem would be that Ethernet II frames contain all kinds of packets, and afaik that cannot be directly reliably routed over PPP? Due to requirements of configuration etc.?

I don't see why you couldn't encapsulate all Ethernet frames. In such scenario, you would be able to effectively merge two remote LANs into one broadcast domain. Meaning that a host in LAN1 would be able to reach a host in LAN2 with ARP. I've done this kind of things in the past - not through PPP but rather over encrypted, BGP-driven tunnels, but the concept is the same. This can open a number of use cases, long-range EtherDFS communication is just one of them.

The only issue you will run into is fragmentation, since a PPP carrier might have a significantly lower MTU than what a typical Ethernet host expects . I do not know PPP, maybe it has some provisions for this, but if not then you would need to explicitly support IP fragmentation (or even better, design your own custom fragment-reassembly protocol that would also work with non-IP traffic).

superfury wrote on 2024-09-25, 13:15:

Or should I should adjust my server and client to send the whole Ethernet II frame as data

This, yes. Then it would be a generic "L2-eth-bridging-over-PPP" solution, and not just some exotic EtherDFS-over-PPP extension.

http://mateusz.viste.fr | gopher://gopher.viste.fr

Reply 4 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++
mateusz.viste wrote on 2024-09-25, 13:28:
I don't see why you couldn't encapsulate all Ethernet frames. In such scenario, you would be able to effectively merge two remot […]
Show full quote
superfury wrote on 2024-09-25, 13:15:

The main issue with full Ethernet-over-modem would be that Ethernet II frames contain all kinds of packets, and afaik that cannot be directly reliably routed over PPP? Due to requirements of configuration etc.?

I don't see why you couldn't encapsulate all Ethernet frames. In such scenario, you would be able to effectively merge two remote LANs into one broadcast domain. Meaning that a host in LAN1 would be able to reach a host in LAN2 with ARP. I've done this kind of things in the past - not through PPP but rather over encrypted, BGP-driven tunnels, but the concept is the same. This can open a number of use cases, long-range EtherDFS communication is just one of them.

The only issue you will run into is fragmentation, since a PPP carrier might have a significantly lower MTU than what a typical Ethernet host expects . I do not know PPP, maybe it has some provisions for this, but if not then you would need to explicitly support IP fragmentation (or even better, design your own custom fragment-reassembly protocol that would also work with non-IP traffic).

superfury wrote on 2024-09-25, 13:15:

Or should I should adjust my server and client to send the whole Ethernet II frame as data

This, yes. Then it would be a generic "L2-eth-bridging-over-PPP" solution, and not just some exotic EtherDFS-over-PPP extension.

Does such a thing exist already in the official PPP specs? Just checking I'm not overlapping with an existing PPP protocol.
There exists PPPoE, but that's the inverse of this?
There's BCP, but that's for older Ethernet standards, not Ethernet II?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 10, by mateusz.viste

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-09-25, 13:30:

Does such a thing exist already in the official PPP specs? Just checking I'm not overlapping with an existing PPP protocol.
There exists PPPoE, but that's the inverse of this?
There's BCP, but that's for older Ethernet standards, not Ethernet II?

I am not familiar with the PPP ecosystem, but BCP (RFC 3518) does look very much like what I was thinking about.

http://mateusz.viste.fr | gopher://gopher.viste.fr

Reply 6 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++
mateusz.viste wrote on 2024-09-25, 13:51:
superfury wrote on 2024-09-25, 13:30:

Does such a thing exist already in the official PPP specs? Just checking I'm not overlapping with an existing PPP protocol.
There exists PPPoE, but that's the inverse of this?
There's BCP, but that's for older Ethernet standards, not Ethernet II?

I am not familiar with the PPP ecosystem, but BCP (RFC 3518) does look very much like what I was thinking about.

But it doesn't support Ethernet II afaik? Also, it looks pretty complicated to implement.

Other than that, won't it cause trouble with nesting packets inside itself? Since the packet server would have to be in promiscious mode for that, it would route it's own packets which would reach a deadloop? It receives it's own packets it sends to it's clients (in my case PPP over TCP/IP over Ethernet II) after all? Full Ethernet II that's routed through PPP would cause such an issue? It would drown itself in it's own sent TCP packets? Or does the card simply need to be in non-promiscuous mode (only receiving broadcasts and it's own MAC address) to fix that? What about conflicts with other PPP protocols routed to Ethernet II protocols?

The basic framework I made already solves the addressing part, at least. The main issue is the data (Ethetnet II protocol itself)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++

Did some thinking about the Ethernet II support.

It doesn't seem feasable, due to complexities of the packets sent/received.
It would also conflict with itself if two sides want to support only a select few packet types to be sent.
You'd also need routing support for Ethernet II MAC addresses on both sides, which isn't implemented right now. That would make the executable even larger than it is right now.

Right now I managed to connect through EDFS on 3 different methods:
- Direct PPP with another EDFSPPP instance over 2 modems(one for each side) (using /r on one of the two sides and /d on the opposite driver (on the other end of the dial-up connection)).
- Normal PPP through UniPCemu's packet server also seems to work the same. It just has the real Ethernet II network when receiving/sending the frames. So both clients in normal dial mode dialling the UniPCemu PPP server. They send their packets to UniPCemu, which will send it to either the real Ethernet network or to it's internal loopback adapter (if not using the real network, which is configured). It then receives the packet from the real network or loopback adapter and relays it to the assigned device connected through PPP (this is the same for it's IPX and IPv4 packets). It does perform a filter when receiving the packet, though, where it must match either the broadcast MAC(FF:FF:FF:FF:FF:FF) or the client's MAC address. If it doesn't, the client won't receive the packet.
When the EDFSPPP clients are using a direct connection to each other without UniPCemu though, all packets will simply received as-is. It doesn't filter the incoming packets' destination MAC address, so for example 11:22:33:44:55:66 will receive packets with destination 77:88:99:AA:BB:CC.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 8 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++

Improved the driver a little bit. I modified the /s (lowercase s, not uppercase) to become /g instead. That way it's /g and /t for give(/g, with the address specified) and take(/t) remoteMAC address. If neither is used, it's rejected and not used.

You use those two flags to specify the MAC address the other side receives:
- Give: give it the MAC address specified (use like /g:1.2.3.4.5.6 to set it for a MAC address, which is required if this is used).
- Take: take the MAC address the opposite side requests.
- Neither: give the opposite side no MAC address to use.

That way you can control the MAC adress of the opposite side of the link.
The original /S (suggest MAC address for us to use) has no effect on this. It just controls what MAC address we request. If not, it will request the default MAC address, the opposite side's result (accept(used that address)/reject(no MAC provided, if it's the same client it's not having it's /t or /g flags)/NAK(uses the specified address instead, which would be it's given /g flag setting).

That way, it can connect to either another PPP server (like UniPCemu) or to another copy of itself.

Another nice thing is that it also has the /r flag, which makes it instead of dialing somewhere, answer the modem instead (the dial steps becoming: disable autoanswer (wait for OK before the next step), wait for RING (the other side calling), answer the ring once it rings with the ATA command).

If it negotiates a MAC address for it to use or remote MAC address to use for the remote has an effect on the functionality enabled.
The remote MAC address affects if it responds to an ARP request with an ARP reply with the remote address as a response (so sending any ARP request will give an ARP reply back specifying the remote address (also written to edfs-up.bat)).
The answer mode also rejects the authentication options, to prevent having to supply it itself (as it doesn't have the functionality implemented to do so).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 10, by GrizzlyAdams

User metadata
Rank Newbie
Rank
Newbie

There is something that was long ago created to be much lighter weight, SLEEP - Serial Line Ethernet Encapsulation Protocol. Its just Ethernet frames encapsulated in SLIP encoding.

Insert a SLIP Frame End (0xC0) between ethernet frames, and encode the frames with the escape bytes (0xC0 in original data becomes [0xDB, 0xDC] and 0xDB in original data becomes [0xDB, 0xDD]).

PLIP also is a thing, and already encapsulates full ethernet frames, and has an available packet driver (with source!) for DOS part of the crynwr collection.

Reply 10 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++
GrizzlyAdams wrote on 2024-09-26, 23:27:

There is something that was long ago created to be much lighter weight, SLEEP - Serial Line Ethernet Encapsulation Protocol. Its just Ethernet frames encapsulated in SLIP encoding.

Insert a SLIP Frame End (0xC0) between ethernet frames, and encode the frames with the escape bytes (0xC0 in original data becomes [0xDB, 0xDC] and 0xDB in original data becomes [0xDB, 0xDD]).

PLIP also is a thing, and already encapsulates full ethernet frames, and has an available packet driver (with source!) for DOS part of the crynwr collection.

But isn't SLIP/PLIP meant for IPv4 packets only? Btw already implemented the same SLIP but using IPX frames instead of IP packets. So that would be 'SLIPX' instead of 'SLIP'. I can easily add the EDFS protocol to do the same.

The main issue is also that no SLIP encapsulated non-IP drivers exist. For this protocol it would become SLEDFS. Lol, that sounds like Sled-FS.
That does make me remember I didn't add it to my packet server's text-based handling yet (using text-based login, like selecting the IPX protocol after receiving "protocol:", followed by the MAC address being sent to the client in text, before switching to SLIP packet mode. Already implemented that for SLIPX(currently 'ipxslip'), but didn't yet for SLEDFS. Maybe it'd be smart to rename the ipxslip mode to slipx instead. And 'ethernetslip' to 'sleep' (that's what it really is)? And ofc add 'sledfs'.

Edit: Added what's essentially SLEDFS on the UniPCemu packet server a while back (based on my old post):
Re: UniPCemu SLIP server releases

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io