Skip to content

Commit 5b78be2

Browse files
committed
feat: parse NetSign protocol
1 parent 48441ad commit 5b78be2

File tree

20 files changed

+822
-10
lines changed

20 files changed

+822
-10
lines changed

agent/crates/enterprise-utils/src/lib.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,52 @@ pub mod l7 {
357357
}
358358

359359
pub mod rpc {
360+
pub mod net_sign {
361+
use public::l7_protocol::LogMessageType;
362+
363+
pub const PROCESSOR_SIGN: &str = "RAWSignProcessor";
364+
pub const PROCESSOR_VERIFY: &str = "PBCRAWVerifyProcessor";
365+
366+
#[derive(Default, Debug, Clone)]
367+
pub struct NetSignFields {
368+
pub processor_name: String,
369+
pub operation: String,
370+
pub result_code: String,
371+
pub biz_data_parts: Vec<String>,
372+
pub sig_present: bool,
373+
pub sig_len: u32,
374+
pub cert_id: String,
375+
pub cert_serial: String,
376+
pub cert_validity: String,
377+
pub issuer_dn_ca: String,
378+
pub app_ver: String,
379+
}
380+
381+
impl NetSignFields {
382+
pub fn trace_id(&self) -> &str {
383+
self.biz_data_parts.get(0).map(|s| s.as_str()).unwrap_or("")
384+
}
385+
pub fn biz_system(&self) -> &str {
386+
self.biz_data_parts.get(6).map(|s| s.as_str()).unwrap_or("")
387+
}
388+
pub fn signer_id(&self) -> String {
389+
String::new()
390+
}
391+
}
392+
393+
#[derive(Default)]
394+
pub struct NetSignParser;
395+
396+
impl NetSignParser {
397+
pub fn check_payload(&self, _: &[u8]) -> Option<LogMessageType> {
398+
unimplemented!()
399+
}
400+
pub fn parse_payload(&self, _: &[u8]) -> Option<NetSignFields> {
401+
unimplemented!()
402+
}
403+
}
404+
}
405+
360406
pub mod iso8583 {
361407
use public::bitmap::Bitmap;
362408

agent/crates/public/src/codecs/hessian2.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,18 @@ impl Hessian2Decoder {
9090
}
9191
}
9292
// int
93-
0x80..=0xbf | 0xc0..=0xcf | 0xd0..=0xd7 | BC_INT => {
94-
Self::to_hessian_value(Self::decode_i32(bytes, start), bytes.len(), HessianValue::Int)
95-
}
93+
0x80..=0xbf | 0xc0..=0xcf | 0xd0..=0xd7 | BC_INT => Self::to_hessian_value(
94+
Self::decode_i32(bytes, start),
95+
bytes.len(),
96+
HessianValue::Int,
97+
),
9698
// long
9799
0xd8..=0xef | 0xf0..=0xff | 0x38..=0x3f | BC_LONG_INT | BC_LONG => {
98-
Self::to_hessian_value(Self::decode_i64(bytes, start), bytes.len(), HessianValue::Long)
100+
Self::to_hessian_value(
101+
Self::decode_i64(bytes, start),
102+
bytes.len(),
103+
HessianValue::Long,
104+
)
99105
}
100106
// date
101107
BC_DATE | BC_DATE_MINUTE => Self::to_hessian_value(
@@ -139,12 +145,18 @@ impl Hessian2Decoder {
139145
None => (None, bytes.len()),
140146
},
141147
// hashmap
142-
BC_MAP | BC_MAP_UNTYPED => {
143-
Self::to_hessian_value(self.decode_map(bytes, start), bytes.len(), HessianValue::Map)
144-
}
148+
BC_MAP | BC_MAP_UNTYPED => Self::to_hessian_value(
149+
self.decode_map(bytes, start),
150+
bytes.len(),
151+
HessianValue::Map,
152+
),
145153
// object,只能处理为 hashmap
146154
BC_OBJECT_DEF | BC_OBJECT | BC_OBJECT_DIRECT..=BC_OBJECT_DIRECT_MAX => {
147-
Self::to_hessian_value(self.decode_obj(bytes, start), bytes.len(), HessianValue::Map)
155+
Self::to_hessian_value(
156+
self.decode_obj(bytes, start),
157+
bytes.len(),
158+
HessianValue::Map,
159+
)
148160
}
149161
_ => (None, bytes.len()), // 如果不符合任何一种,表示这个 tag 没有意义,直接丢弃剩余所有数据
150162
}

agent/crates/public/src/l7_protocol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub enum L7Protocol {
6363
SomeIp = 47,
6464
Iso8583 = 48,
6565
Triple = 49,
66+
NetSign = 50,
6667

6768
// SQL
6869
MySQL = 60,
@@ -149,6 +150,7 @@ impl From<String> for L7Protocol {
149150
"tls" => Self::TLS,
150151
"ping" => Self::Ping,
151152
"some/ip" | "someip" => Self::SomeIp,
153+
"netsign" | "net-sign" | "net_sign" => Self::NetSign,
152154
_ => Self::Unknown,
153155
}
154156
}

agent/src/common/l7_protocol_info.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ cfg_if::cfg_if! {
131131
PingInfo(PingInfo),
132132
CustomInfo(CustomInfo),
133133
Iso8583Info(crate::flow_generator::protocol_logs::rpc::Iso8583Info),
134+
NetSignInfo(crate::flow_generator::protocol_logs::rpc::NetSignInfo),
134135
// add new protocol info below
135136
);
136137
}

agent/src/common/l7_protocol_log.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ macro_rules! impl_protocol_parser {
103103
#[cfg(feature = "enterprise")]
104104
"ISO-8583"=>Ok(Self::Iso8583(Default::default())),
105105
#[cfg(feature = "enterprise")]
106+
"NetSign"|"netsign"|"net_sign"=>Ok(Self::NetSign(Default::default())),
107+
#[cfg(feature = "enterprise")]
106108
"WebSphereMQ"=>Ok(Self::WebSphereMq(Default::default())),
107109
$(
108110
stringify!($proto) => Ok(Self::$proto(Default::default())),
@@ -202,6 +204,7 @@ cfg_if::cfg_if! {
202204
Tars(TarsLog),
203205
Oracle(crate::flow_generator::protocol_logs::OracleLog),
204206
Iso8583(crate::flow_generator::protocol_logs::Iso8583Log),
207+
NetSign(crate::flow_generator::protocol_logs::NetSignLog),
205208
MQTT(MqttLog),
206209
AMQP(AmqpLog),
207210
NATS(NatsLog),

agent/src/config/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,6 +2044,7 @@ impl Default for Filters {
20442044
("Tars".to_string(), "1-65535".to_string()),
20452045
("SomeIP".to_string(), "1-65535".to_string()),
20462046
("ISO8583".to_string(), "1-65535".to_string()),
2047+
("NetSign".to_string(), "1-65535".to_string()),
20472048
("Triple".to_string(), "1-65535".to_string()),
20482049
("MySQL".to_string(), "1-65535".to_string()),
20492050
("PostgreSQL".to_string(), "1-65535".to_string()),
@@ -2076,6 +2077,7 @@ impl Default for Filters {
20762077
("Tars".to_string(), vec![]),
20772078
("SomeIP".to_string(), vec![]),
20782079
("ISO8583".to_string(), vec![]),
2080+
("NetSign".to_string(), vec![]),
20792081
("Triple".to_string(), vec![]),
20802082
("MySQL".to_string(), vec![]),
20812083
("PostgreSQL".to_string(), vec![]),

agent/src/ebpf/kernel/include/common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ enum traffic_protocol {
7777
PROTO_TARS = 46,
7878
PROTO_SOME_IP = 47,
7979
PROTO_ISO8583 = 48,
80+
PROTO_TRIPLE = 49,
81+
PROTO_NET_SIGN = 50,
8082
PROTO_MYSQL = 60,
8183
PROTO_POSTGRESQL = 61,
8284
PROTO_ORACLE = 62,

agent/src/ebpf/kernel/include/protocol_inference.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,56 @@ 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 + tail(4B)
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+
1294+
// outer_len field [3..12] must be ASCII decimal digits
1295+
if (buf[3] < '0' || buf[3] > '9')
1296+
return MSG_UNKNOWN;
1297+
// First inner TLV tag must be TAG_PROCESSOR_NAME (0x01)
1298+
if ((uint8_t)buf[13] != 0x01)
1299+
return MSG_UNKNOWN;
1300+
// processorName len field [15..26]: leading bytes must be ASCII '0'
1301+
if (buf[15] != '0' || buf[24] != '0')
1302+
return MSG_UNKNOWN;
1303+
1304+
// RAWSignProcessor: processorName len = 16, operation tag at [43]
1305+
if (buf[25] == '1' && buf[26] == '6' && (uint8_t)buf[43] == 0x02) {
1306+
if (buf[56] == '7')
1307+
return MSG_REQUEST; // operation = "request"
1308+
if (buf[56] == '8')
1309+
return MSG_RESPONSE; // operation = "response"
1310+
}
1311+
// PBCRAWVerifyProcessor: processorName len = 21, operation tag at [48]
1312+
if (buf[25] == '2' && buf[26] == '1' && (uint8_t)buf[48] == 0x02) {
1313+
if (buf[61] == '7')
1314+
return MSG_REQUEST; // operation = "request"
1315+
if (buf[61] == '8')
1316+
return MSG_RESPONSE; // operation = "response"
1317+
}
1318+
1319+
return MSG_UNKNOWN;
1320+
}
1321+
12721322
#define CSTR_LEN(s) (sizeof(s) / sizeof(char) - 1)
12731323
#define CSTR_MASK(s) ((~0ull) >> (64 - CSTR_LEN(s) * 8))
12741324
// convert const string with length <= 8 for matching
@@ -4145,6 +4195,14 @@ infer_protocol_2(const char *infer_buf, size_t count,
41454195
syscall_infer_len,
41464196
conn_info)) != MSG_UNKNOWN) {
41474197
inferred_message.protocol = PROTO_ISO8583;
4198+
#if defined(LINUX_VER_KFUNC) || defined(LINUX_VER_5_2_PLUS)
4199+
} else if (skip_proto != PROTO_NET_SIGN && (inferred_message.type =
4200+
#else
4201+
} else if ((inferred_message.type =
4202+
#endif
4203+
infer_net_sign_message(infer_buf,
4204+
count, conn_info)) != MSG_UNKNOWN) {
4205+
inferred_message.protocol = PROTO_NET_SIGN;
41484206
#if defined(LINUX_VER_KFUNC) || defined(LINUX_VER_5_2_PLUS)
41494207
} else if (skip_proto != PROTO_MEMCACHED && (inferred_message.type =
41504208
#else
@@ -4493,6 +4551,14 @@ infer_protocol_1(struct ctx_info_s *ctx,
44934551
return inferred_message;
44944552
}
44954553
break;
4554+
case PROTO_NET_SIGN:
4555+
if ((inferred_message.type =
4556+
infer_net_sign_message(infer_buf, count,
4557+
conn_info)) != MSG_UNKNOWN) {
4558+
inferred_message.protocol = PROTO_NET_SIGN;
4559+
return inferred_message;
4560+
}
4561+
break;
44964562
case PROTO_MEMCACHED:
44974563
if ((inferred_message.type =
44984564
infer_memcached_message(infer_buf, count,

agent/src/ebpf/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ pub const SOCK_DATA_SOME_IP: u16 = 47;
6969
#[allow(dead_code)]
7070
pub const SOCK_DATA_ISO8583: u16 = 48;
7171
#[allow(dead_code)]
72+
pub const SOCK_DATA_TRIPLE: u16 = 49;
73+
#[allow(dead_code)]
74+
pub const SOCK_DATA_NET_SIGN: u16 = 50;
75+
#[allow(dead_code)]
7276
pub const SOCK_DATA_MYSQL: u16 = 60;
7377
#[allow(dead_code)]
7478
pub const SOCK_DATA_POSTGRESQL: u16 = 61;

agent/src/ebpf/user/ctrl_tracer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ static void datadump_help(void)
147147
fprintf(stderr, " 46: PROTO_TARS\n");
148148
fprintf(stderr, " 47: PROTO_SOME_IP\n");
149149
fprintf(stderr, " 48: PROTO_ISO8583\n");
150+
fprintf(stderr, " 49: PROTO_TRIPLE\n");
151+
fprintf(stderr, " 50: PROTO_NET_SIGN\n");
150152
fprintf(stderr, " 60: PROTO_MYSQL\n");
151153
fprintf(stderr, " 61: PROTO_POSTGRESQL\n");
152154
fprintf(stderr, " 62: PROTO_ORACLE\n");

0 commit comments

Comments
 (0)