The piece of code you show is doing exactly that: it is checking that there is a packet (of size 8 to 99 bytes, beginning with "SSH-") in both directions. Since client and server are supposed to talk somewhat simultaneously, the detection engine cannot assume that it will see the packet from the client or the packet from the server first; and knowing which side of the connection is the "client" might be difficult anyway in the context of packet-by-packet processing.
So the code you show uses a flag called packet_direction
which has value 0 or 1, for the two possible directions. I will thereafter call direction 0 "AtoB" and direction 1 "BtoA" (it does not really matter whether A or B is the client at the TCP level). The code also uses an internal flag ssh_stage
, initially at 0. When a first packet which matches the conditions (size 8 to 99 bytes, begins with "SSH-") is detected, the first half of the code is used (since ssh_stage
is 0 at that point), and ssh_stage
is set to 1 if this first packet is in the "AtoB" direction, 2 if it is in the "BtoA" direction.
When a second matching packet arrives, packet_direction
is now set to the direction of that second packet. If that second packet is in the same direction as the first packet, then the current value of ssh_stage
will not match the expression 2 - packet->packet_direction
; however, it will match it if the second packet comes from the other direction (e.g. the second packet is in "BtoA" while the first packet was in "AtoB").
To sum up, the code checks that there are indeed two "SSH-looking" packets in opposite directions, as opposed to two successive packets in the same flow direction.
What you should do depends on how reliable you want your engine to be. If you only require two SSH-looking packets without considering direction, you might get some false positives, in case a non-SSH client happens to send two such packets to a non-SSH server. Requiring that the two packets flow in opposite directions will trigger fewer false positives. Note that the ndpi
code is already not 100% reliable.
Indeed, if you look at RFC 4253:
- The initial strings sent by both client and server may have length up to 255 characters, not 99.
- After the exchange of the version strings, the connection setup dialog continues with some extra data from the client, which the client is allowed to send immediately, possibly in the same packet as its version string, so the client payload length might be way above 255 bytes.
- The server is allowed to send some extra lines of characters before its version string, so the server packet payload length may also exceed 255, and it does not necessarily begin with "SSH-".
So the ndpi
code may miss some perfectly standard SSH connections. It is up to you to decide whether you want to miss more or fewer such connections. Of course, the more reliable you want your code to be, the more work you will have to do...