1818#ifndef AF_INET
1919#define AF_INET 2
2020#endif
21+ #ifndef AF_INET6
22+ #define AF_INET6 10
23+ #endif
2124
2225#ifndef DNS_PORT
2326#define DNS_PORT 53
@@ -51,12 +54,12 @@ struct dns_recv_args {
5154
5255struct dns_connect_args {
5356 int fd ;
54- const struct sockaddr * addr ;
55- __u32 addrlen ;
57+ __u16 family ;
58+ __u16 port ;
5659};
5760
5861struct {
59- __uint (type , BPF_MAP_TYPE_HASH );
62+ __uint (type , BPF_MAP_TYPE_LRU_HASH );
6063 __uint (max_entries , 16384 );
6164 __type (key , struct dns_query_key );
6265 __type (value , struct dns_query_state );
@@ -157,16 +160,38 @@ static __always_inline int parse_dns_response(const void *payload, __u64 len,
157160static __always_inline int is_dns_destination (const struct sockaddr * addr , __u32 addrlen )
158161{
159162 struct sockaddr_in dst ;
163+ struct sockaddr_in6 dst6 ;
164+
165+ if (!addr ) {
166+ return 0 ;
167+ }
168+
169+ if (addrlen >= sizeof (struct sockaddr_in )) {
170+ if (bpf_probe_read_user (& dst , sizeof (dst ), addr ) == 0 ) {
171+ if (dst .sin_family == AF_INET && bpf_ntohs (dst .sin_port ) == DNS_PORT ) {
172+ return 1 ;
173+ }
174+ }
175+ }
160176
161- if (! addr || addrlen < sizeof (struct sockaddr_in )) {
177+ if (addrlen < sizeof (struct sockaddr_in6 )) {
162178 return 0 ;
163179 }
164180
165- if (bpf_probe_read_user (& dst , sizeof (dst ), addr ) != 0 ) {
181+ if (bpf_probe_read_user (& dst6 , sizeof (dst6 ), addr ) != 0 ) {
166182 return 0 ;
167183 }
168184
169- if (dst .sin_family != AF_INET || bpf_ntohs (dst .sin_port ) != DNS_PORT ) {
185+ if (dst6 .sin6_family != AF_INET6 || bpf_ntohs (dst6 .sin6_port ) != DNS_PORT ) {
186+ return 0 ;
187+ }
188+
189+ return 1 ;
190+ }
191+
192+ static __always_inline int is_dns_family_port (__u16 family , __u16 port )
193+ {
194+ if ((family != AF_INET && family != AF_INET6 ) || port != DNS_PORT ) {
170195 return 0 ;
171196 }
172197
@@ -179,15 +204,39 @@ int trace_dns_connect_enter(struct syscall_trace_enter *ctx)
179204 __u32 tid ;
180205 __u64 pid_tgid ;
181206 struct dns_connect_args args ;
207+ __u16 family ;
208+ __u16 port ;
209+ struct sockaddr sa ;
210+ struct sockaddr_in sa4 ;
211+ struct sockaddr_in6 sa6 ;
182212
183213 args .fd = (int ) ctx -> args [0 ];
184- args . addr = ( const struct sockaddr * ) ctx -> args [ 1 ] ;
185- args . addrlen = ( __u32 ) ctx -> args [ 2 ] ;
214+ family = 0 ;
215+ port = 0 ;
186216
187- if (!args . addr ) {
217+ if (!ctx -> args [ 1 ] ) {
188218 return 0 ;
189219 }
190220
221+ if (bpf_probe_read_user (& sa , sizeof (sa ), (const void * ) ctx -> args [1 ]) != 0 ) {
222+ return 0 ;
223+ }
224+
225+ family = sa .sa_family ;
226+ if (family == AF_INET && (__u32 ) ctx -> args [2 ] >= sizeof (struct sockaddr_in )) {
227+ if (bpf_probe_read_user (& sa4 , sizeof (sa4 ), (const void * ) ctx -> args [1 ]) == 0 ) {
228+ port = bpf_ntohs (sa4 .sin_port );
229+ }
230+ }
231+ else if (family == AF_INET6 && (__u32 ) ctx -> args [2 ] >= sizeof (struct sockaddr_in6 )) {
232+ if (bpf_probe_read_user (& sa6 , sizeof (sa6 ), (const void * ) ctx -> args [1 ]) == 0 ) {
233+ port = bpf_ntohs (sa6 .sin6_port );
234+ }
235+ }
236+
237+ args .family = family ;
238+ args .port = port ;
239+
191240 pid_tgid = bpf_get_current_pid_tgid ();
192241 tid = (__u32 ) pid_tgid ;
193242
@@ -217,20 +266,42 @@ int trace_dns_connect_exit(struct syscall_trace_exit *ctx)
217266 }
218267
219268 ret = ctx -> ret ;
220- if (ret == 0 && is_dns_destination (args -> addr , args -> addrlen )) {
269+ key .pid = pid ;
270+ key .fd = args -> fd ;
271+
272+ if (ret == 0 && is_dns_family_port (args -> family , args -> port )) {
221273 mntns_id = gadget_get_mntns_id ();
222274 if (!gadget_should_discard_mntns_id (mntns_id )) {
223- key .pid = pid ;
224- key .fd = args -> fd ;
225275 bpf_map_update_elem (& dns_sockets , & key , & mntns_id , BPF_ANY );
226276 }
227277 }
278+ else {
279+ bpf_map_delete_elem (& dns_sockets , & key );
280+ }
228281
229282 bpf_map_delete_elem (& dns_connect_pending , & tid );
230283
231284 return 0 ;
232285}
233286
287+ SEC ("tracepoint/syscalls/sys_enter_close" )
288+ int trace_dns_close_enter (struct syscall_trace_enter * ctx )
289+ {
290+ __u64 pid_tgid ;
291+ __u32 pid ;
292+ struct dns_socket_key key ;
293+
294+ pid_tgid = bpf_get_current_pid_tgid ();
295+ pid = (__u32 ) (pid_tgid >> 32 );
296+
297+ key .pid = pid ;
298+ key .fd = (__s32 ) ((int ) ctx -> args [0 ]);
299+
300+ bpf_map_delete_elem (& dns_sockets , & key );
301+
302+ return 0 ;
303+ }
304+
234305SEC ("tracepoint/syscalls/sys_enter_sendto" )
235306int trace_dns_sendto_enter (struct syscall_trace_enter * ctx )
236307{
0 commit comments