-
Notifications
You must be signed in to change notification settings - Fork 1
NTR Packet Format
The Header is 84 bytes in total, comprised of 21 (unsigned) 32-bit integers.
The individual fields are as follows:
- magic number (should always be 0x12345678)
- currentSeq / seq
- type
- command
- arguments. Each argument is an unsigned 32-bit int, and there are 16 of them.
- dataLen. Size of the Data Section, in bytes.
Following the Header is the Data Section. The size can be an arbitrary number of bytes, and is indicated by the dataLen field in the Header.
The "seq" variable is more or less an ID number, unique to each pair of packets (the one sent by the client, and the response from NTR.)
For a fuller implementation, for each new packet either increment seq or set it to a random number.
For a more hacky approach, you can ignore it and set it to 0; it'll function fine for most purposes. Actually, due to the nature of TCP as well as that NTR (probably) isn't doing multithreaded packet stuff, seq may be entirely redundant and unnecessary.
For every packet received which causes a response packet to be sent, the seq variable of the response packet is kept the same as whatever it was in the received packet. This happens automatically; the response packet is (usually?) built from the received packet by changing variables in the header.
As a matter of fact, in the whole codebase the seq variable of a given packet is only referred two twice; once in the packet struct definition, and once when printing a debug string. It's also never assigned a value, except for initialization (which is implicitly 0).
In the original NTRClient code, the seq variable is incremented by 1000 for every packet sent to NTR.
The seq variable is used here and there, but it's really only consequential in the case of a ReadMem packet.
See: handleReadMem function, in NTRClient/ntrclient/NtrClient.cs
For any received ReadMem packet, if the seq value doesn't match the value of the "lastReadMemSeq" variable, the packet is basically ignored. This allows the client to keep track of which received ReadMem packet corresponds to the ReadMem-request packet which was sent.
However this comes with a major quirk: if two ReadMem requests are sent to NTR in quick succession, NTRClient may ignore one of them. This is admittedly a niche case, but it's not really a good elegant way of handling things. The seq variable could be useful when multiple ReadMem requests are sent in quick succession. But that's not the case for NTRClient's implementation, because dropping all but one of those ReadMem response packets is not desirable behavior, so the client will avoid triggering any case where seq would really be useful.