@@ -1269,6 +1269,63 @@ static __inline enum message_type infer_iso8583_message(const char *buf,
12691269 return MSG_REQUEST;
12701270}
12711271
1272+ // NetSign 签名验签协议推断
1273+ // TCP payload: msgSeq(2B) + outer_type(1B) + outer_len(10 ASCII digits) + inner TLVs
1274+ // Inner TLV: tag(1B) + type(1B) + len(12 ASCII digits) + value
1275+ //
1276+ // Known processor names and their lengths:
1277+ // RAWSignProcessor (len=16): operation tag at byte[43], len field ends at byte[56]
1278+ // PBCRAWVerifyProcessor (len=21): operation tag at byte[48], len field ends at byte[61]
1279+ // operation len last byte: '7' → "request", '8' → "response"
1280+ static __inline enum message_type infer_net_sign_message (const char *buf,
1281+ size_t count,
1282+ struct conn_info_s
1283+ *conn_info)
1284+ {
1285+ if (!protocol_port_check_2 (PROTO_NET_SIGN, conn_info))
1286+ return MSG_UNKNOWN;
1287+ if (conn_info->tuple .l4_protocol != IPPROTO_TCP || count < 62 )
1288+ return MSG_UNKNOWN;
1289+ if (is_infer_socket_valid (conn_info->socket_info_ptr )) {
1290+ if (conn_info->socket_info_ptr ->l7_proto != PROTO_NET_SIGN)
1291+ return MSG_UNKNOWN;
1292+ /*
1293+ * Socket already confirmed as NetSign. Continuation reads (mid-message
1294+ * syscall splits) do not start at message offset 0, so the byte-pattern
1295+ * checks below would fail. Return MSG_REQUEST unconditionally here; the
1296+ * Rust-level parser derives the real message type from the TLV content.
1297+ */
1298+ return MSG_REQUEST;
1299+ }
1300+
1301+ // outer_len field [3..12] must be ASCII decimal digits
1302+ if (buf[3 ] < ' 0' || buf[3 ] > ' 9' )
1303+ return MSG_UNKNOWN;
1304+ // First inner TLV tag must be TAG_PROCESSOR_NAME (0x01)
1305+ if ((uint8_t )buf[13 ] != 0x01 )
1306+ return MSG_UNKNOWN;
1307+ // processorName len field [15..26]: leading bytes must be ASCII '0'
1308+ if (buf[15 ] != ' 0' || buf[24 ] != ' 0' )
1309+ return MSG_UNKNOWN;
1310+
1311+ // RAWSignProcessor: processorName len = 16, operation tag at [43]
1312+ if (buf[25 ] == ' 1' && buf[26 ] == ' 6' && (uint8_t )buf[43 ] == 0x02 ) {
1313+ if (buf[56 ] == ' 7' )
1314+ return MSG_REQUEST; // operation = "request"
1315+ if (buf[56 ] == ' 8' )
1316+ return MSG_RESPONSE; // operation = "response"
1317+ }
1318+ // PBCRAWVerifyProcessor: processorName len = 21, operation tag at [48]
1319+ if (buf[25 ] == ' 2' && buf[26 ] == ' 1' && (uint8_t )buf[48 ] == 0x02 ) {
1320+ if (buf[61 ] == ' 7' )
1321+ return MSG_REQUEST; // operation = "request"
1322+ if (buf[61 ] == ' 8' )
1323+ return MSG_RESPONSE; // operation = "response"
1324+ }
1325+
1326+ return MSG_UNKNOWN;
1327+ }
1328+
12721329#define CSTR_LEN (s ) (sizeof (s) / sizeof (char ) - 1 )
12731330#define CSTR_MASK (s ) ((~0ull ) >> (64 - CSTR_LEN(s) * 8 ))
12741331// convert const string with length <= 8 for matching
@@ -4145,6 +4202,14 @@ infer_protocol_2(const char *infer_buf, size_t count,
41454202 syscall_infer_len,
41464203 conn_info)) != MSG_UNKNOWN) {
41474204 inferred_message.protocol = PROTO_ISO8583;
4205+ #if defined(LINUX_VER_KFUNC) || defined(LINUX_VER_5_2_PLUS)
4206+ } else if (skip_proto != PROTO_NET_SIGN && (inferred_message.type =
4207+ #else
4208+ } else if ((inferred_message.type =
4209+ #endif
4210+ infer_net_sign_message (infer_buf,
4211+ count, conn_info)) != MSG_UNKNOWN) {
4212+ inferred_message.protocol = PROTO_NET_SIGN;
41484213#if defined(LINUX_VER_KFUNC) || defined(LINUX_VER_5_2_PLUS)
41494214 } else if (skip_proto != PROTO_MEMCACHED && (inferred_message.type =
41504215#else
@@ -4493,6 +4558,14 @@ infer_protocol_1(struct ctx_info_s *ctx,
44934558 return inferred_message;
44944559 }
44954560 break ;
4561+ case PROTO_NET_SIGN:
4562+ if ((inferred_message.type =
4563+ infer_net_sign_message (infer_buf, count,
4564+ conn_info)) != MSG_UNKNOWN) {
4565+ inferred_message.protocol = PROTO_NET_SIGN;
4566+ return inferred_message;
4567+ }
4568+ break ;
44964569 case PROTO_MEMCACHED:
44974570 if ((inferred_message.type =
44984571 infer_memcached_message (infer_buf, count,
0 commit comments