|
| 1 | +/* |
| 2 | + light weight TLS tracker. |
| 3 | +*/ |
| 4 | + |
| 5 | +#ifndef __TLS_TRACKER_H__ |
| 6 | +#define __TLS_TRACKER_H__ |
| 7 | +#include "utils.h" |
| 8 | + |
| 9 | +#define CONTENT_TYPE_CHANGE_CIPHER 0x14 |
| 10 | +#define CONTENT_TYPE_ALERT 0x15 |
| 11 | +#define CONTENT_TYPE_HANDSHAKE 0x16 |
| 12 | +#define CONTENT_TYPE_APP_DATA 0x17 |
| 13 | +#define HANDSHAKE_CLIENT_HELLO 0x01 |
| 14 | +#define HANDSHAKE_SERVER_HELLO 0x02 |
| 15 | + |
| 16 | +// https://www.rfc-editor.org/rfc/rfc5246 |
| 17 | +struct tls_record { |
| 18 | + u8 content_type; // handshake, alert, change cipher, app data |
| 19 | + u8 major; |
| 20 | + u8 minor; |
| 21 | + u16 length; |
| 22 | +}; |
| 23 | + |
| 24 | +struct tls_handshake_header { |
| 25 | + u8 content_type; // client hello, server hello ... |
| 26 | + u8 len[3]; |
| 27 | +}; |
| 28 | + |
| 29 | +struct tls_handshake_version { |
| 30 | + u8 major; |
| 31 | + u8 minor; |
| 32 | +}; |
| 33 | + |
| 34 | +// Extract TLS info |
| 35 | +static inline void track_tls_version(struct __sk_buff *skb, pkt_info *pkt) { |
| 36 | + if (pkt->id->transport_protocol == IPPROTO_TCP) { |
| 37 | + void *data_end = (void *)(long)skb->data_end; |
| 38 | + struct tcphdr *tcp = (struct tcphdr *)pkt->l4_hdr; |
| 39 | + if (!tcp || ((void *)tcp + sizeof(*tcp) > data_end)) { |
| 40 | + return; |
| 41 | + } |
| 42 | + |
| 43 | + u8 len = tcp->doff * sizeof(u32); |
| 44 | + if (!len) { |
| 45 | + return; |
| 46 | + } |
| 47 | + |
| 48 | + struct tls_record rec; |
| 49 | + u32 offset = (long)pkt->l4_hdr - (long)skb->data + len; |
| 50 | + |
| 51 | + if ((bpf_skb_load_bytes(skb, offset, &rec, sizeof(rec))) < 0) { |
| 52 | + return; |
| 53 | + } |
| 54 | + |
| 55 | + switch (rec.content_type) { |
| 56 | + case CONTENT_TYPE_HANDSHAKE: { |
| 57 | + pkt->ssl_version = ((u16)rec.major) << 8 | rec.minor; |
| 58 | + struct tls_handshake_header handshake; |
| 59 | + if (bpf_skb_load_bytes(skb, offset + sizeof(rec), &handshake, sizeof(handshake)) < 0) { |
| 60 | + return; |
| 61 | + } |
| 62 | + if (handshake.content_type == HANDSHAKE_CLIENT_HELLO || |
| 63 | + handshake.content_type == HANDSHAKE_SERVER_HELLO) { |
| 64 | + struct tls_handshake_version handshake_version; |
| 65 | + if (bpf_skb_load_bytes(skb, offset + sizeof(rec) + sizeof(handshake), |
| 66 | + &handshake_version, sizeof(handshake_version)) < 0) { |
| 67 | + return; |
| 68 | + } |
| 69 | + pkt->ssl_version = ((u16)handshake_version.major) << 8 | handshake_version.minor; |
| 70 | + } |
| 71 | + break; |
| 72 | + } |
| 73 | + case CONTENT_TYPE_CHANGE_CIPHER: |
| 74 | + case CONTENT_TYPE_ALERT: |
| 75 | + case CONTENT_TYPE_APP_DATA: |
| 76 | + pkt->ssl_version = ((u16)rec.major) << 8 | rec.minor; |
| 77 | + break; |
| 78 | + } |
| 79 | + } |
| 80 | +} |
| 81 | + |
| 82 | +#endif // __TLS_TRACKER_H__ |
0 commit comments