networking · advanced · ~15 min
Read a tiny but real wire-protocol header.
Every TLS connection starts with a 5-byte record header. Parse it from a byte buffer — no crypto involved, just reading fixed fields.
The header layout is:
byte 0: content_type (20=ChangeCipherSpec, 21=Alert, 22=Handshake, 23=ApplicationData)
byte 1: legacy_version_major (always 0x03)
byte 2: legacy_version_minor (0x01=TLS 1.0, 0x02=1.1, 0x03=1.2, 0x04=1.3)
bytes 3-4: length (big-endian, <= 0x4000 for a valid TLS record)
Implement int parse_tls_record_header(const unsigned char *buf, int len, int *out_type, int *out_minor, int *out_length) that parses the header and fills the three output values.
buf, len: the record bytes and how many are available.out_type, out_minor, out_length: set to content_type, legacy_version_minor, and length on success.Returns 1 on success (header valid and outputs populated), or 0 otherwise.
{22, 3, 3, 0x01, 0x00} -> 1, type=22, minor=3, length=256
{23, 3, 4, 0x50, 0x00} -> 0 (length 0x5000 exceeds 0x4000)
0x03.0x4000 (the max valid TLS record length).(buf[3] << 8) | buf[4].Every TLS connection starts with a 5-byte record header. Knowing the layout demystifies the protocol; you can parse a capture without writing crypto.
Record bytes (buf) and available length (len), plus three out-pointers for type, minor version, and length.
Returns 1 with the three outputs populated on success, or 0 otherwise.
Require >= 5 bytes; require major version 0x03; read length big-endian and reject if > 0x4000.
#include <stddef.h>
int parse_tls_record_header(const unsigned char *buf, int len, int *out_type, int *out_minor, int *out_length) { /* TODO */ (void)buf; (void)len; (void)out_type; (void)out_minor; (void)out_length; return 0; }
Reading length in little-endian. Accepting length > 0x4000.
Length exactly 0x4000. Type outside the known set (allowed but uncommon).
O(1).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.