xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/tools/quic_packet_printer_bin.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // clang-format off
6 
7 // Dumps out the decryptable contents of a QUIC packet in a human-readable way.
8 // If the packet is null encrypted, this will dump full packet contents.
9 // Otherwise it will dump the header, and fail with an error that the
10 // packet is undecryptable.
11 //
12 // Usage: quic_packet_printer server|client <hex dump of packet>
13 //
14 // Example input:
15 // quic_packet_printer server 0c6b810308320f24c004a939a38a2e3fd6ca589917f200400201b80b0100501c0700060003023d0000001c00556e656e637279707465642073747265616d2064617461207365656e
16 //
17 // Example output:
18 // OnPacket
19 // OnUnauthenticatedPublicHeader
20 // OnUnauthenticatedHeader: { connection_id: 13845207862000976235, connection_id_length:8, packet_number_length:1, multipath_flag: 0, reset_flag: 0, version_flag: 0, path_id: , packet_number: 4 }
21 // OnDecryptedPacket
22 // OnPacketHeader
23 // OnAckFrame:  largest_observed: 1 ack_delay_time: 3000 missing_packets: [  ] is_truncated: 0 received_packets: [ 1 at 466016  ]
24 // OnStopWaitingFrame
25 // OnConnectionCloseFrame: error_code { 61 } error_details { Unencrypted stream data seen }
26 
27 // clang-format on
28 
29 #include <iostream>
30 
31 #include "absl/strings/escaping.h"
32 #include "absl/strings/string_view.h"
33 #include "quiche/quic/core/quic_framer.h"
34 #include "quiche/quic/core/quic_types.h"
35 #include "quiche/quic/core/quic_utils.h"
36 #include "quiche/quic/platform/api/quic_flags.h"
37 #include "quiche/common/platform/api/quiche_command_line_flags.h"
38 #include "quiche/common/quiche_text_utils.h"
39 
40 DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, quic_version, "",
41                                 "If set, specify the QUIC version to use.");
42 
43 namespace quic {
44 
45 class QuicPacketPrinter : public QuicFramerVisitorInterface {
46  public:
QuicPacketPrinter(QuicFramer * framer)47   explicit QuicPacketPrinter(QuicFramer* framer) : framer_(framer) {}
48 
OnError(QuicFramer * framer)49   void OnError(QuicFramer* framer) override {
50     std::cerr << "OnError: " << QuicErrorCodeToString(framer->error())
51               << " detail: " << framer->detailed_error() << "\n";
52   }
OnProtocolVersionMismatch(ParsedQuicVersion received_version)53   bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
54     framer_->set_version(received_version);
55     std::cerr << "OnProtocolVersionMismatch: "
56               << ParsedQuicVersionToString(received_version) << "\n";
57     return true;
58   }
OnPacket()59   void OnPacket() override { std::cerr << "OnPacket\n"; }
OnVersionNegotiationPacket(const QuicVersionNegotiationPacket &)60   void OnVersionNegotiationPacket(
61       const QuicVersionNegotiationPacket& /*packet*/) override {
62     std::cerr << "OnVersionNegotiationPacket\n";
63   }
OnRetryPacket(QuicConnectionId,QuicConnectionId,absl::string_view,absl::string_view,absl::string_view)64   void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
65                      QuicConnectionId /*new_connection_id*/,
66                      absl::string_view /*retry_token*/,
67                      absl::string_view /*retry_integrity_tag*/,
68                      absl::string_view /*retry_without_tag*/) override {
69     std::cerr << "OnRetryPacket\n";
70   }
OnUnauthenticatedPublicHeader(const QuicPacketHeader &)71   bool OnUnauthenticatedPublicHeader(
72       const QuicPacketHeader& /*header*/) override {
73     std::cerr << "OnUnauthenticatedPublicHeader\n";
74     return true;
75   }
OnUnauthenticatedHeader(const QuicPacketHeader & header)76   bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
77     std::cerr << "OnUnauthenticatedHeader: " << header;
78     return true;
79   }
OnDecryptedPacket(size_t,EncryptionLevel level)80   void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
81     // This only currently supports "decrypting" null encrypted packets.
82     QUICHE_DCHECK_EQ(ENCRYPTION_INITIAL, level);
83     std::cerr << "OnDecryptedPacket\n";
84   }
OnPacketHeader(const QuicPacketHeader &)85   bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
86     std::cerr << "OnPacketHeader\n";
87     return true;
88   }
OnCoalescedPacket(const QuicEncryptedPacket &)89   void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {
90     std::cerr << "OnCoalescedPacket\n";
91   }
OnUndecryptablePacket(const QuicEncryptedPacket &,EncryptionLevel,bool)92   void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
93                              EncryptionLevel /*decryption_level*/,
94                              bool /*has_decryption_key*/) override {
95     std::cerr << "OnUndecryptablePacket\n";
96   }
OnStreamFrame(const QuicStreamFrame & frame)97   bool OnStreamFrame(const QuicStreamFrame& frame) override {
98     std::cerr << "OnStreamFrame: " << frame;
99     std::cerr << "         data: { "
100               << absl::BytesToHexString(
101                      absl::string_view(frame.data_buffer, frame.data_length))
102               << " }\n";
103     return true;
104   }
OnCryptoFrame(const QuicCryptoFrame & frame)105   bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
106     std::cerr << "OnCryptoFrame: " << frame;
107     std::cerr << "         data: { "
108               << absl::BytesToHexString(
109                      absl::string_view(frame.data_buffer, frame.data_length))
110               << " }\n";
111     return true;
112   }
OnAckFrameStart(QuicPacketNumber largest_acked,QuicTime::Delta)113   bool OnAckFrameStart(QuicPacketNumber largest_acked,
114                        QuicTime::Delta /*ack_delay_time*/) override {
115     std::cerr << "OnAckFrameStart, largest_acked: " << largest_acked;
116     return true;
117   }
OnAckRange(QuicPacketNumber start,QuicPacketNumber end)118   bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
119     std::cerr << "OnAckRange: [" << start << ", " << end << ")";
120     return true;
121   }
OnAckTimestamp(QuicPacketNumber packet_number,QuicTime timestamp)122   bool OnAckTimestamp(QuicPacketNumber packet_number,
123                       QuicTime timestamp) override {
124     std::cerr << "OnAckTimestamp: [" << packet_number << ", "
125               << timestamp.ToDebuggingValue() << ")";
126     return true;
127   }
OnAckFrameEnd(QuicPacketNumber start,const std::optional<QuicEcnCounts> & ecn_counts)128   bool OnAckFrameEnd(QuicPacketNumber start,
129                      const std::optional<QuicEcnCounts>& ecn_counts) override {
130     std::cerr << "OnAckFrameEnd, start: " << start;
131     if (ecn_counts.has_value()) {
132       std::cerr << "  ECN counts: " << ecn_counts->ToString();
133     }
134     return true;
135   }
OnStopWaitingFrame(const QuicStopWaitingFrame & frame)136   bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
137     std::cerr << "OnStopWaitingFrame: " << frame;
138     return true;
139   }
OnPaddingFrame(const QuicPaddingFrame & frame)140   bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
141     std::cerr << "OnPaddingFrame: " << frame;
142     return true;
143   }
OnPingFrame(const QuicPingFrame & frame)144   bool OnPingFrame(const QuicPingFrame& frame) override {
145     std::cerr << "OnPingFrame: " << frame;
146     return true;
147   }
OnRstStreamFrame(const QuicRstStreamFrame & frame)148   bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
149     std::cerr << "OnRstStreamFrame: " << frame;
150     return true;
151   }
OnConnectionCloseFrame(const QuicConnectionCloseFrame & frame)152   bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
153     // The frame printout will indicate whether it's a Google QUIC
154     // CONNECTION_CLOSE, IETF QUIC CONNECTION_CLOSE/Transport, or IETF QUIC
155     // CONNECTION_CLOSE/Application frame.
156     std::cerr << "OnConnectionCloseFrame: " << frame;
157     return true;
158   }
OnNewConnectionIdFrame(const QuicNewConnectionIdFrame & frame)159   bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
160     std::cerr << "OnNewConnectionIdFrame: " << frame;
161     return true;
162   }
OnRetireConnectionIdFrame(const QuicRetireConnectionIdFrame & frame)163   bool OnRetireConnectionIdFrame(
164       const QuicRetireConnectionIdFrame& frame) override {
165     std::cerr << "OnRetireConnectionIdFrame: " << frame;
166     return true;
167   }
OnNewTokenFrame(const QuicNewTokenFrame & frame)168   bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
169     std::cerr << "OnNewTokenFrame: " << frame;
170     return true;
171   }
OnStopSendingFrame(const QuicStopSendingFrame & frame)172   bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
173     std::cerr << "OnStopSendingFrame: " << frame;
174     return true;
175   }
OnPathChallengeFrame(const QuicPathChallengeFrame & frame)176   bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
177     std::cerr << "OnPathChallengeFrame: " << frame;
178     return true;
179   }
OnPathResponseFrame(const QuicPathResponseFrame & frame)180   bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
181     std::cerr << "OnPathResponseFrame: " << frame;
182     return true;
183   }
OnGoAwayFrame(const QuicGoAwayFrame & frame)184   bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
185     std::cerr << "OnGoAwayFrame: " << frame;
186     return true;
187   }
OnMaxStreamsFrame(const QuicMaxStreamsFrame & frame)188   bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
189     std::cerr << "OnMaxStreamsFrame: " << frame;
190     return true;
191   }
OnStreamsBlockedFrame(const QuicStreamsBlockedFrame & frame)192   bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
193     std::cerr << "OnStreamsBlockedFrame: " << frame;
194     return true;
195   }
OnWindowUpdateFrame(const QuicWindowUpdateFrame & frame)196   bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
197     std::cerr << "OnWindowUpdateFrame: " << frame;
198     return true;
199   }
OnBlockedFrame(const QuicBlockedFrame & frame)200   bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
201     std::cerr << "OnBlockedFrame: " << frame;
202     return true;
203   }
OnMessageFrame(const QuicMessageFrame & frame)204   bool OnMessageFrame(const QuicMessageFrame& frame) override {
205     std::cerr << "OnMessageFrame: " << frame;
206     return true;
207   }
OnHandshakeDoneFrame(const QuicHandshakeDoneFrame & frame)208   bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
209     std::cerr << "OnHandshakeDoneFrame: " << frame;
210     return true;
211   }
OnAckFrequencyFrame(const QuicAckFrequencyFrame & frame)212   bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
213     std::cerr << "OnAckFrequencyFrame: " << frame;
214     return true;
215   }
OnResetStreamAtFrame(const QuicResetStreamAtFrame & frame)216   bool OnResetStreamAtFrame(const QuicResetStreamAtFrame& frame) override {
217     std::cerr << "OnResetStreamAtFrame: " << frame;
218     return true;
219   }
OnPacketComplete()220   void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; }
IsValidStatelessResetToken(const StatelessResetToken &) const221   bool IsValidStatelessResetToken(
222       const StatelessResetToken& /*token*/) const override {
223     std::cerr << "IsValidStatelessResetToken\n";
224     return false;
225   }
OnAuthenticatedIetfStatelessResetPacket(const QuicIetfStatelessResetPacket &)226   void OnAuthenticatedIetfStatelessResetPacket(
227       const QuicIetfStatelessResetPacket& /*packet*/) override {
228     std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n";
229   }
OnKeyUpdate(KeyUpdateReason reason)230   void OnKeyUpdate(KeyUpdateReason reason) override {
231     std::cerr << "OnKeyUpdate: " << reason << "\n";
232   }
OnDecryptedFirstPacketInKeyPhase()233   void OnDecryptedFirstPacketInKeyPhase() override {
234     std::cerr << "OnDecryptedFirstPacketInKeyPhase\n";
235   }
AdvanceKeysAndCreateCurrentOneRttDecrypter()236   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
237       override {
238     std::cerr << "AdvanceKeysAndCreateCurrentOneRttDecrypter\n";
239     return nullptr;
240   }
CreateCurrentOneRttEncrypter()241   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
242     std::cerr << "CreateCurrentOneRttEncrypter\n";
243     return nullptr;
244   }
245 
246  private:
247   QuicFramer* framer_;  // Unowned.
248 };
249 
250 }  // namespace quic
251 
main(int argc,char * argv[])252 int main(int argc, char* argv[]) {
253   const char* usage = "Usage: quic_packet_printer client|server <hex>";
254   std::vector<std::string> args =
255       quiche::QuicheParseCommandLineFlags(usage, argc, argv);
256 
257   if (args.size() < 2) {
258     quiche::QuichePrintCommandLineFlagHelp(usage);
259     return 1;
260   }
261 
262   std::string perspective_string = args[0];
263   quic::Perspective perspective;
264   if (perspective_string == "client") {
265     perspective = quic::Perspective::IS_CLIENT;
266   } else if (perspective_string == "server") {
267     perspective = quic::Perspective::IS_SERVER;
268   } else {
269     std::cerr << "Invalid perspective" << std::endl;
270     quiche::QuichePrintCommandLineFlagHelp(usage);
271     return 1;
272   }
273   std::string hex;
274   if (!absl::HexStringToBytes(args[1], &hex)) {
275     std::cerr << "Invalid hex string" << std::endl;
276     return 1;
277   }
278   quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
279   // Fake a time since we're not actually generating acks.
280   quic::QuicTime start(quic::QuicTime::Zero());
281   quic::QuicFramer framer(versions, start, perspective,
282                           quic::kQuicDefaultConnectionIdLength);
283   const quic::ParsedQuicVersion& version = quic::ParseQuicVersionString(
284       quiche::GetQuicheCommandLineFlag(FLAGS_quic_version));
285   if (version != quic::ParsedQuicVersion::Unsupported()) {
286     framer.set_version(version);
287   }
288   quic::QuicPacketPrinter visitor(&framer);
289   framer.set_visitor(&visitor);
290   quic::QuicEncryptedPacket encrypted(hex.c_str(), hex.length());
291   return framer.ProcessPacket(encrypted);
292 }
293