From eeb15e8f7b9b2a76dd67456d7ed8540f63c3a5fa Mon Sep 17 00:00:00 2001 From: gbucchino Date: Thu, 23 Jan 2025 16:49:49 +0100 Subject: [PATCH] Update project --- dns-trace | Bin 18624 -> 17896 bytes src/common.h | 10 +- src/dns-trace.c | 107 +- src/dns-trace.ebpf.c | 64 +- src/dns-trace.ebpf.o | Bin 39712 -> 37200 bytes src/vmlinux.h | 193060 +++++++++++++++++++++++++--------------- 6 files changed, 123245 insertions(+), 69996 deletions(-) diff --git a/dns-trace b/dns-trace index cf30db0745ebf6c31336db2b5b2ca34ac898fae6..41f6cdb420660734711c36f5d41b9659a4dcac50 100755 GIT binary patch literal 17896 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 z literal 18624 zcmeHPe{@t;e!r6+5J8fl;6`xQw+ad>Awl^eZgeKegbABK2npg3cuq2tADYa>nKuv+ zO5C8`F^wCy>aneyV!Nm7cGs3J?MhuMC>$w!JRaDyTHB>H<)}Lmbh9ch?IP39_ul(` zd2g86{y3*+|H;jH?|Z+W?~nWA-FM%e`y;#j4Rv`QkKm9mZWqMuo2d{l3w#_A!YfvY z>9}7lz9OaoF2Lp0;!N6=rvyxkv|c_a**&l2ne-~H$CPtOla?S}DP5%ON~_$oOBZ5<3#0Qz)j@Wn+HO?aF&(E2 zAu#3oBsX*&(e;^0Ysm8muwcq|>tILu{GSG{_GX=4u6h~Q z`Ddz&D;D>3w=KJ6aZhMbPj@8Izo>u3vPH{oDUV0Xm&kI@LPn@ftyQnR*&VmSv6jY~o@gZ85^U=U3)AfEjYiD46^vP?DWqyv#aMTw(`-w0bcAE3 z*%$5U5iX=777mNHz78|mc7M1Xu6m-ukPGPOj)ctKV4v9$GTXM9kzlXepuHy=cO%lG zFBa{L1$$j4jF~~p3buF2WNfU%oouu(95Fk(QB+rcBjK$g9&LXhY>6%_8i|YUNZ2wX zRx~K$-JOwOkLXKSak{m41!JNQ##V>u4fn=j(T1W3M94w3&l24ovN%>0c(`8#W1W3w zUoeK^m}Yx_5Xr+~_jY2@m$mEK?hSTF1bEaMb!HV5Z>QKYv8tiIy2e~mzNCDqK(xB4 z&a5b}K!4|8mOGhBCv&TlS%$WdC;Pj6+|^%!q=lNJ-f#-OkomZ#B1ZkC(ooIFBRt}J zXj{~W8n_a3x-TJ{{lF-AV7EuhiErLgQ6k{!pvLZ${1owq=GRHSQ2evz?~;6h_(1a; zB%dcf1y6y$pZvWW(Jw`r{ys9^q;Vqyzg@o+6&d&{je9fjCXF{`;319oW#AEw@6Et} zPva@CEQa8GGVk@dan5%j1Aj`Ft0@C7)BMH^TxkCI9m+p_)98E0;T;D)gF(_yow>5#~6fEcYo%|?Z|&w)>O;9U+}4?(50&w&>^ z^!pt+UKBeFIB-1#m$Gj?@vA0wW+>M;;$u|>EUG&%?$*(4!y5_NclCLJ7y5zCFl3z(Yb;V;N zl3zkRb-`l;%D!BPjuG%ORDM*SJh3^DJQWyxZ@j6cVYu)m)J0%;#(GJricxdv*%uZG z@ma~$wIr!}0uBSig;WoLThCdu@wnfHoF4Zj>Cuv_2gvbZO`#u@`b()?frS?W$??Fe zAKwvp^;~|y^LpUK1#1=@yr3NvrAIqtI&42swGeh9vA8ubSoJuxL?HRTb!lLzYCFo2 zT7()*b>a4Up$B@NO>D<>>>&tSVUyf>CXh^w29mAs1cv;$ybA(J|G9^EorPnW%LG-FH>uF07@vcO>S+>Re!`6&^|{delp8Mw~9w47J$P(+^O?I(^B=Y0t<3 z5^p+8Y2&3ZIQ^skaS|N$pCgOFaN{^R9rB;4PagA0o4+S{@^#eQFHzpqV_&4xNQ2bQ z9h2^oJI^02+(mVPFk&ZB5lHTQ=ODcqsn5@+(J)NUbUL3H&7e=LdJ5 z7uzm}^SjYzQ+uFz05z08y(=*6AAO11(JQ!6%SThA5Oy5(kIocG{~bcUB7MB45_y8e zN&hL70r@{KZ3D?Sp>{pg9yzpap)#YA%s^tYaH$7i1#M`Ny-GVDfGQelsuabeOj<>_ zd#uvaSHb>cyl|=U-yoj`xDSXsMcifJ-UX+8m%!u5NT#O(Yc)I->}tk6->RVdt~%+P zQpiIJE8yih^7%OVTn_GO;s%IY2yTeD7;$sK4G&=@t`8<70Su-$u{dlqYuEFOmDRR+|Y{D-$64V-?{5;x33aLVsC+z z%(f-pwIxMTGR2k*Ye~tA-b?8Pq_+Pla-|+ml%&H|pWDD@+fgZAh~J?3Qi6fOL$g$7 zer{{tqD-lT%Gb4QI`AZl3hSxVPYhT6*w*ma8qX+=&7>g^}#g z%b!g&X*lm0WZ zdnVNaQaxd-{voRlFBOoG#otPc)ZosPNL&Mp&(M3P{*=5hQMr)@ClOEj z-x%`0A(g&kE8R>=!>y2<^c|q#P9S;Wr6r(LFZBFReNG)~N`5_F0z~zlNB#BD)IX7J z(vP9o&f_An4jHRZok;TVLIpjb7N{Af5^anCORMY1ZWiX_#UaAv@M+?8W zj#9zrZrV`cS;QYXlsH1RWcHN9^+Iw@ipLIjjQH+s7_R!oHA46{)F~ot8bhY`pGD?g{UYC*Tlw>nt3^ZdlZNESwaH)j(zD(T3?B9bZvEH9 zhcvdlXOr(<-zMK?pNVh2ppm8=gStkYl=@_ttbxfIn5==x8uKtx zjXV&EZjFfgHKJy{s0oO`da-7`Xsi{Db)sgCuhB2oul0$>YSFk#G&YMhtql$0&abZ* zO)bqLP`{>bt!PyDjiO~^3-a(&d|n>^ES=tiYd@}IxZcHe7T0vhzKUx(u0~w<;fmvW z6xSc&`T?$kxayl$%B+U^qA?56&@>UBh_=Lnk$AA(>W)T?`dWzlr-|n9gNbn5GOTTV z;gyDXkk+e|kD8ufJPxQuNos>uPzmC(_Qjz{e32DH&6I~}T_-9gYL8Z;WbMh-s0o}_ z$_%w^CVI^f+^LG6(4d7dWf?NCf@VmaP}rh{HYDgsLu%@!FtN3#uOhyrqT^<_=#k63!n!~Yh_sMb9n9yqb?j0Dui6atE+GDtH&DL0>f}T(F4t>(G%^A z3oE)Pny|2nCYopkjd0C(g?sw&YkqG2ZT%=NO}ae$Q96AD^r~N`(`P_$0;K`-%<*)( z03)Yi(0QOIL1`^}95e*_;;+)_-JqUN(&_JjZU;RAT8j4Z9_VH~{{oC;pT*#29w?1d zdq8KwHwDl3X5r~C^~}9=YSD;iYANBgo-y)qI(;K4=#X7shPj(%RI9ES}B%!dl~ZGkRNr~zh>K?1b!pxbG1wEx8>)7w?e+nCAVz( zRVepgLH;zApVQBO!b1vI0iwMS^YC2Oxa9S={9fSApQh7a!*iLiU!F(yRA;od-G}G6 z32{+fT>7oN`r@+3^ZmufaDl&g!5kMs;x+ z^s9@D<%7M}g&MFQjEv6wx{tg5EAIQaXa=N*OA&95eGO=nB9BiVS6% zI`^y)q|JozDg~~$1vVz17UT2u|y-(K|4`CC~Z5a9Hvwoe<{uCC~M&-T%(WsNS!ZnSo`xJ=AHsLDLRRw`lsPrcZ177n=S^ z)7Le9Thk9T{an*2dXv)?nqH^rGEM6=-JofQrdu?9RMV$5%`6A=DX)rg`)9m%&3XgB z{4t4li}&lf3fm<~ZccHHs%>45QW6$*YY z-S`yy{dMD01-ElIUL^SaaO0NDEW@<#i$|o-eKxqgnAeV!)S8pL_oa8NE*h;#cVjM8)X4l81W6W&~HDIUd4G zQAN)1RgLp^mu1Tl@n9z*=ZDgxP=m{prQYrbPX75jPP!Df;PQxz>;Ea>+4BFK)Sn|p ze25@$^ZGvG9@N{om(Yp5ss|7!oZovc_I{0Xzrf$Omw{70x!>3Uo&wFykRPv3cZEcS zcoUTL@6($+`MY*f4zMYxa1VBh zayvW(i~``S^)^H5UnUCXOEuRmTRqPuM|duo?VmPKc(4;Svz;&1`aB-t1OgJj_E~VCzg-FaZ27-22Y!1Fd{Yj*F9-gO9Qa;|7mJy? zJ+IZp_$3q;8YKzUUxlwltZ5el7?GVawWjC)z1yUXXafgQeL;wa>A)m8454Z z;yUT4SQxrp$vI5OuE%pJMgO+frxi8%K<0DeJ9VSRH{{6A?i~1Yz{!7Rdw43mV5 z7armwmWV{KQbR}_nQ9mE)RBoZNpX1!sk~C3W(ou&p&qQx$s2P?kZt|d*OQ4R0xgggmGddOL%=oSP1ewc19(;2lndj)7E-Ljirbo^- zr%vzDc`}!qiF0T!7>yHajOq}YZXOwO*O5T?;kFFTP&{gO$+m@~gKOb4)EzMs@i1D( z#6zXV?0TrQN@?o!CbA2PGP$J ztA%@)g(#12>$QSypjJ%LE{@4%{60~R<^OPbXCzVHmgvSY>+X<-eAV@ftYD{*vaVpf zOO%JUMc_|SE2bn{!m&7(&RvWNSuETWBm*7m>#;<+YzyUxmUl+MTH$`&sbhpvRK8{9 z;V#`3c7@=CIc2K)L}kHovZA!$K;|ph+ue@5L@i1N2ra0Wqs54FbkWprX8A_^Um*HL zgikoek}B};ai%;Uro~d1<3z8;MN>m;&%fK5&Lbs9z~{;pmVtBH^Y446hD&?m_X@+c zh+ywul+)*V0H&Ni&)f0*7~8Kw1fys>|2$v7^ni9u^L$iKY>yGS3>$FA5W=?Sc|oSO zK&f9;f182RoEzt#=O38zgbwGQ^_V^Ydz!;zp64l;4(N0#|D?nD*Ra@*2t5qMT?8zq6{&8SbuRM=RLr)nr<@rvH%Di%%XcCvx-q3bT z2T14$8ScfCkU8ynzJ)30mt8Q=bWeso&&x19!HU`er_cWWJj0&nt(o%tE$h>>a)$4L zq5Sjn6NZ**I%o?No{=5#H-Me?yRT7tO!;@cLN9**4rbWf^G4J$AQb&K=^uj*&8g5k zM1g-7^Z(b#%rEmy--1mEF1F|2;br=`3hR+?3d}S8cVJY0w&!^QL)#yM%oz+PgZRg| zsO_>n|K8{Sf5QLggxfc#%kAJ9*gDha`LE-PAwXE5h<#^!roV>7X)nB5wL;P3nq|Uv zOv%`3Kk8MQquQSG=M09EL7e7S$QPHN=ehbTm7<}DedlsBFkPpwlVe!0{q;7YB9vDO zPMXogqclient)); + char *req_type, *class, *type; + printf("%s:%-10d", inet_ntoa(*(struct in_addr*)&s_event->client), s_event->dport); + printf("%-5x", s_event->tid); + + req_type = mapReqType(s_event->req_type); + printf("%-10s", req_type); + free(req_type); + + printf("%-30s", s_event->qname); + + class = mapClass(s_event->class); + printf("%-10s", class); + free(class); + + type = mapType(s_event->type); + printf("%-10s", type); + free(type); + + if (s_event->req_type == REQ_ANSWER){ + printf("%-15s", inet_ntoa(*(struct in_addr*)&s_event->ans)); + printf("%-5d", s_event->ttl); + } + + + /*printf("IP: %s\n", inet_ntoa(*(struct in_addr*)&s_event->client)); printf("dport: %d\n", s_event->dport); printf("sport: %d\n", s_event->sport); printf("Transaction ID: %x\n", s_event->tid); @@ -205,9 +244,9 @@ int handle_event(void *ctx, void *data, size_t data_sz){ if (s_event->req_type == REQ_ANSWER) printf("Data: %s\n", inet_ntoa(*(struct in_addr*)&s_event->ans)); - + */ printf("\n"); - + return 0; } int main(int argc, char *argv[]){ @@ -253,8 +292,8 @@ int main(int argc, char *argv[]){ } bpf_program__attach(programSkb); - int sock = open_raw_sock("wlp0s20f3"); - //int sock = open_raw_sock("enx98e743c667fc"); + // int sock = open_raw_sock("wlp0s20f3"); + int sock = open_raw_sock("enx98e743c667fc"); printf("Socket: %d\n", sock); int prog_fd = bpf_program__fd(programSkb); printf("Program fd: %d\n", prog_fd); diff --git a/src/dns-trace.ebpf.c b/src/dns-trace.ebpf.c index 3023a03..04e6459 100644 --- a/src/dns-trace.ebpf.c +++ b/src/dns-trace.ebpf.c @@ -55,7 +55,7 @@ static size_t get_labels2(struct __sk_buff *skb, size_t offset, struct event *s_ } s_event->qname[qname_len - 1] = '\0'; qname_len++; - bpf_printk("qname: %s", s_event->qname); + // bpf_printk("qname: %s", s_event->qname); // bpf_printk("qname len: %d", qname_len); return qname_len; } @@ -161,7 +161,7 @@ static size_t get_answer(struct __sk_buff *skb, struct event *s_event, size_t tl bpf_skb_load_bytes(skb, tlen, &ttl, sizeof(uint32_t)); tlen += 2; bpf_printk("offset: %d", tlen); - bpf_printk("ttl: %d", ntohs(ttl)); + s_event->ttl = ntohs(ttl); // Get data size uint16_t size; @@ -185,31 +185,28 @@ static size_t get_answer(struct __sk_buff *skb, struct event *s_event, size_t tl static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){ struct event *s_event; struct dnshdr dns = {0}; - // bpf_printk("udp len: %d", ntohs(udp.len)); - - s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0); - if (!s_event) - return 0; - - /* Get IP header */ - s_event->client = ip.saddr; + struct query_section dquery = {0}; /* Get DNS header */ bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr), &dns, sizeof(struct dnshdr)); // Check OpCode - uint16_t flags = ntohs(dns.flags); - uint16_t qr = flags & 0xF000; // Get the QR code: 0 -> query, 1 -> response - if (qr == 0x0) - s_event->req_type = REQ_QUERY; - else if(qr == 0x8000) - bpf_printk("Response"); - bpf_printk("Flags: %x %x", flags, qr); - - if (ntohs(dns.nbQuestions) == 0){ - bpf_ringbuf_discard(s_event, 0); + uint16_t qr = ntohs(dns.flags) & 0xF000; // Get the QR code: 0 -> query, 1 -> response + /* If it's not a query, we do not continue */ + if(qr != 0x0) return 0; - } + + if (ntohs(dns.nbQuestions) == 0) + return 0; + + s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0); + if (!s_event) + return 0; + + s_event->req_type = REQ_QUERY; + + /* Get IP header */ + s_event->client = ip.saddr; s_event->tid = ntohs(dns.transactionID); @@ -242,7 +239,6 @@ static void dnsanswer_old(struct __sk_buff *skb, struct iphdr ip, struct udphdr if (payload_len <= -1) { bpf_printk("payload len %d", payload_len); } - // Get udp len //udplen = ntohs(udp.len); @@ -252,7 +248,6 @@ static void dnsanswer_old(struct __sk_buff *skb, struct iphdr ip, struct udphdr //if (udplen <= 0) // return 0; - /*if (offset + udplen > skb->len) { bpf_printk("outbound"); plen = sizeof(struct dnshdr); @@ -284,26 +279,23 @@ static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp, if (bpf_skb_load_bytes(skb, offset, &dns, 12) < 0) return; + // Check OpCode + uint16_t qr = ntohs(dns.flags) & 0xF000; // Get the QR code: 0 -> query, 1 -> response + if(qr != 0x8000) // Not a response, we do not continue + return; + + if (ntohs(dns.nbQuestions) == 0) + return; + s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0); if (!s_event) return; + s_event->req_type = REQ_ANSWER; + /* Get IP header */ s_event->client = ip.daddr; - // Check OpCode - uint16_t flags = ntohs(dns.flags); - uint16_t qr = flags & 0xF000; // Get the QR code: 0 -> query, 1 -> response - if (qr == 0x0) // Query - s_event->req_type = REQ_QUERY; - else if(qr == 0x8000) // Response - s_event->req_type = REQ_ANSWER; - - if (ntohs(dns.nbQuestions) == 0){ - bpf_ringbuf_discard(s_event, 0); - return; - } - s_event->dport = dport; s_event->sport = sport; diff --git a/src/dns-trace.ebpf.o b/src/dns-trace.ebpf.o index bbbb9e0c5af03286b40f3a0430082d4b645484b7..d6e1eb6d7aba6146f14267befec8799f022850d6 100644 GIT binary patch literal 37200 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⁢nNO}IDE!o+3?Vr{>Z0baf!ofKRp-UcfuaGB zaI3?;4)1rk&*1|O4>)|>;X#K_Iy~&~X@^G~KI3pn-stu=`&*3m0uJ8^uW-2D;Y|)V zIK0K-E{FFx-0Sduhx;5p;P8OM#~n8NWv0F-o$z6YPdhx~@EM2AD-UBo-y7ZDzQw#A zRXA+EQ(=0B*E!+!4sUYU?5COZTb%Glhg%))b$GwS=KYGXf4~VJu$be??5~;j7_`D! zzmpEX7=co|FTfwP_(kxL#h(LL>bUfnAMe49qx}X0@EP9daF@fq4);0S@9==bgASi^ zc-Y|)hXor-JC?V^Vc+2zhwB|~aJbRoE{A&^?sK@`;Q@yS9X{pou)`w`3q7CM1hW1P z`wrJQT<>s$!;KDiIo#`TpTqqQ4>&yN@F|Cf9UgI5==qSXzr()6X1y@+>z#139+>b( zC%ntyUWfY}?ss^=;X#K_IXvv}h{N(F8Vd_2`#-E?!)CwSaE%jQ?{I^|jShD?-0N_k z!~G5qI6Ua^DTjw09&uQ{B-B-w^|#hLvhQ$>!}Si^-;FSRqZ8icaIeFC4);4e;P9Zs zryL%3c*J4(Qq-=$-Vdfq*5Bb8hwB~Yk2sB!^>?_-;a-RP9PW2`z~MoMPdPm7Fn{!E z9IsdTdcT%Ba=F9mfBIsmzCUonH#xk;;Z}$DIK1EC0}dZ`__)I-9UgM{w8Li{&d*nM zGxaNXxWeH&hc`LA#o<j<3!7`fK7R^md#N){=lCM(+2SOlegnfpKHQjP_YA39W9;X{88a* z{y;I#Kh%uBzn=ZG7BY8LD*VVXY1_eHf5u-)SAQ1Lj@FqN`!mIAlp)i!O;o4%w$s;t zu-()x`!_YNyZrK+_(ei`wbHMRuO-&T*J!QuYvZdFu2`vk{FQjds?}JFl6LZM<1lCZ z&3fG<|1`6sZW-WmYQO`g3n>y!4Ga zy_q-4S}uRX??hszUttv5@6+k|Zq;@sf8&1*fkw9DeM6@=?@3IU8~4iy7_a>*T2u;O z_aEDjZRfTh?YTCY@>A1z#$Q=>`rnPqch|0t>F!~MaEJ6ho}#gF`R;tY@^5NYDF&t} zpXLg2xaGeby7BU#U7^wqI|IXwy8+S0%m2(?onGIkFn?~by7@OiN1N_A`O`8e;hwVY zbI2xtPA`TGc`WB!~{ZvK2%?_GD6uf%$BWL>LHZ{jmO eotyuUp>w9Fj5o4bdg6?(DARoohp}hw7yb_mKin+< literal 39712 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 z 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