Trong kiến trúc mở rộng của Wireshark, việc đăng ký bộ phân tích (dissector) là bước thiết yếu để tích hợp hỗ trợ cho giao thức tùy chỉnh. Quá trình này không chỉ khai báo thông tin giao thức mà còn thiết lập cấu trúc hiển thị, định nghĩa trường dữ liệu và liên kết logic xử lý gói tin — tất cả đều xoay quanh nhóm hàm proto_register_*.
Khởi tạo giao thức với proto_register_protocol
Hàm nền tảng đầu tiên là proto_register_protocol(), được gọi trong hàm khởi tạo cụ thể như proto_register_dns() hoặc proto_register_mqtt(). Hàm này trả về một giá trị nguyên duy nhất — gọi là protocol identifier — dùng làm khóa tham chiếu xuyên suốt toàn bộ chuỗi đăng ký.
int proto_dns = -1;
void proto_register_dns(void) {
proto_dns = proto_register_protocol(
"Domain Name System", // Tên đầy đủ
"DNS", // Tên viết tắt hiển thị trong UI
"dns" // Tên bộ lọc (filter name)
);
}
Giá trị trả về phải được lưu vào biến toàn cục có phạm vi file để sử dụng ở các bước tiếp theo. Nếu hàm trả về giá trị âm, quá trình đăng ký thất bại — thường do xung đột tên hoặc thiếu tài nguyên.
Định nghĩa và đăng ký trường dữ liệu
Mỗi giao thức cần mô tả chi tiết các thành phần bên trong gói tin (header fields), ví dụ như "Query Type", "Response Code", hay "Transaction ID". Các trường này được khai báo tĩnh trong mảng kiểu hf_register_info:
static hf_register_info field_definitions[] = {
{ &hf_dns_query_type,
{ "Query Type", "dns.qry.type",
FT_UINT16, BASE_DEC, VALS(dns_qtype_vals), 0x0,
"Type of DNS query", HFILL }
},
{ &hf_dns_response_code,
{ "Response Code", "dns.flags.rcode",
FT_UINT8, BASE_DEC, VALS(dns_rcode_vals), 0xC0,
"DNS response status", HFILL }
}
};
Sau khi khai báo, mảng được truyền vào hàm đăng ký:
proto_register_field_array(proto_dns, field_definitions, G_N_ELEMENTS(field_definitions));
Lưu ý rằng mỗi trường phải gắn với một biến toàn cục (ví dụ hf_dns_query_type) để đảm bảo ánh xạ đúng giữa dữ liệu nhị phân và biểu diễn người dùng.
Thiết lập cây phân tích (protocol tree)
Wireshark hiển thị kết quả phân tích dưới dạng cây phân cấp. Mỗi nút con đại diện cho một lớp logic (ví dụ: "DNS Header", "Question Section"). Việc khai báo các nút này sử dụng mảng con trỏ kiểu gint*:
static gint ett_dns = -1;
static gint ett_dns_question = -1;
static gint ett_dns_answer = -1;
static gint *subtree_ids[] = {
&ett_dns,
&ett_dns_question,
&ett_dns_answer
};
Hàm đăng ký tương ứng là:
proto_register_subtree_array(subtree_ids, G_N_ELEMENTS(subtree_ids));
Các giá trị ett_* sẽ được khởi tạo tự động bởi hệ thống và sau đó được dùng trong hàm phân tích chính để thêm nhánh vào cây hiện tại.
Liên kết bộ phân tích với luồng mạng
Giai đoạn cuối cùng — gọi là handoff — xác định cách Wireshark kích hoạt bộ phân tích khi gặp gói tin phù hợp. Đây là nơi gắn bộ phân tích với bảng phân giải (dissector table), chẳng hạn như "tcp.port", "udp.port", hoặc "ip.proto".
void proto_reg_handoff_dns(void) {
static dissector_handle_t dns_handle = NULL;
if (!dns_handle) {
dns_handle = create_dissector_handle(dissect_dns, proto_dns);
}
dissector_add_uint("udp.port", 53, dns_handle);
dissector_add_uint("tcp.port", 53, dns_handle);
}
Với các giao thức không có cổng cố định (như SSDP hay mDNS), ta dùng cơ chế heuristic:
heur_dissector_add("udp", dissect_dns_heuristic, proto_dns);
Hàm dissect_dns_heuristic() phải kiểm tra nội dung gói và trả về TRUE nếu xác định được giao thức — điều này cho phép nhiều bộ phân tích cạnh tranh trên cùng một cổng.
Tổng quan luồng thực thi
Toàn bộ quy trình đăng ký tuân theo thứ tự nghiêm ngặt:
- Gọi
proto_register_protocol()→ nhậnproto_id - Khai báo và đăng ký mảng
hf_register_info→ tạo metadata trường - Khai báo và đăng ký mảng
ett_*→ xây dựng cấu trúc cây - Gọi
proto_reg_handoff_*→ gắn bộ phân tích vào bảng phân giải hoặc heuristic chain
Bất kỳ sai sót nào trong thứ tự hoặc thiếu bước nào đều dẫn đến lỗi runtime hoặc không hiển thị dữ liệu phân tích.
Chuẩn bị môi trường phát triển
Wireshark cung cấp khuôn mẫu chuẩn trong thư mục doc/packet-TEMPLATE.c, bao gồm skeleton đầy đủ cho hàm đăng ký, handoff và hàm phân tích mẫu. Ngoài ra, tài liệu doc/README.dissector và doc/README.heuristic mô tả chi tiết ngữ nghĩa từng tham số và best practice xử lý bộ nhớ (sử dụng wmem thay vì malloc).