PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/lib/node_modules/pm2/node_modules/systeminformation/lib
Viewing File: /usr/lib/node_modules/pm2/node_modules/systeminformation/lib/network.js
'use strict'; // @ts-check // ================================================================================== // network.js // ---------------------------------------------------------------------------------- // Description: System Information - library // for Node.js // Copyright: (c) 2014 - 2025 // Author: Sebastian Hildebrandt // ---------------------------------------------------------------------------------- // License: MIT // ================================================================================== // 9. Network // ---------------------------------------------------------------------------------- const os = require('os'); const exec = require('child_process').exec; const execSync = require('child_process').execSync; const fs = require('fs'); const util = require('./util'); let _platform = process.platform; const _linux = (_platform === 'linux' || _platform === 'android'); const _darwin = (_platform === 'darwin'); const _windows = (_platform === 'win32'); const _freebsd = (_platform === 'freebsd'); const _openbsd = (_platform === 'openbsd'); const _netbsd = (_platform === 'netbsd'); const _sunos = (_platform === 'sunos'); let _network = {}; let _default_iface = ''; let _ifaces = {}; let _dhcpNics = []; let _networkInterfaces = []; let _mac = {}; let pathToIp; function getDefaultNetworkInterface() { let ifacename = ''; let ifacenameFirst = ''; try { let ifaces = os.networkInterfaces(); let scopeid = 9999; // fallback - "first" external interface (sorted by scopeid) for (let dev in ifaces) { if ({}.hasOwnProperty.call(ifaces, dev)) { ifaces[dev].forEach(function (details) { if (details && details.internal === false) { ifacenameFirst = ifacenameFirst || dev; // fallback if no scopeid if (details.scopeid && details.scopeid < scopeid) { ifacename = dev; scopeid = details.scopeid; } } }); } } ifacename = ifacename || ifacenameFirst || ''; if (_windows) { // https://www.inetdaemon.com/tutorials/internet/ip/routing/default_route.shtml let defaultIp = ''; const cmd = 'netstat -r'; const result = execSync(cmd, util.execOptsWin); const lines = result.toString().split(os.EOL); lines.forEach(line => { line = line.replace(/\s+/g, ' ').trim(); if (line.indexOf('0.0.0.0 0.0.0.0') > -1 && !(/[a-zA-Z]/.test(line))) { const parts = line.split(' '); if (parts.length >= 5) { defaultIp = parts[parts.length - 2]; } } }); if (defaultIp) { for (let dev in ifaces) { if ({}.hasOwnProperty.call(ifaces, dev)) { ifaces[dev].forEach(function (details) { if (details && details.address && details.address === defaultIp) { ifacename = dev; } }); } } } } if (_linux) { let cmd = 'ip route 2> /dev/null | grep default'; let result = execSync(cmd, util.execOptsLinux); let parts = result.toString().split('\n')[0].split(/\s+/); if (parts[0] === 'none' && parts[5]) { ifacename = parts[5]; } else if (parts[4]) { ifacename = parts[4]; } if (ifacename.indexOf(':') > -1) { ifacename = ifacename.split(':')[1].trim(); } } if (_darwin || _freebsd || _openbsd || _netbsd || _sunos) { let cmd = ''; if (_linux) { cmd = 'ip route 2> /dev/null | grep default | awk \'{print $5}\''; } if (_darwin) { cmd = 'route -n get default 2>/dev/null | grep interface: | awk \'{print $2}\''; } if (_freebsd || _openbsd || _netbsd || _sunos) { cmd = 'route get 0.0.0.0 | grep interface:'; } let result = execSync(cmd); ifacename = result.toString().split('\n')[0]; if (ifacename.indexOf(':') > -1) { ifacename = ifacename.split(':')[1].trim(); } } } catch (e) { util.noop(); } if (ifacename) { _default_iface = ifacename; } return _default_iface; } exports.getDefaultNetworkInterface = getDefaultNetworkInterface; function getMacAddresses() { let iface = ''; let mac = ''; let result = {}; if (_linux || _freebsd || _openbsd || _netbsd) { if (typeof pathToIp === 'undefined') { try { const lines = execSync('which ip', util.execOptsLinux).toString().split('\n'); if (lines.length && lines[0].indexOf(':') === -1 && lines[0].indexOf('/') === 0) { pathToIp = lines[0]; } else { pathToIp = ''; } } catch (e) { pathToIp = ''; } } try { const cmd = 'export LC_ALL=C; ' + ((pathToIp) ? pathToIp + ' link show up' : '/sbin/ifconfig') + '; unset LC_ALL'; let res = execSync(cmd, util.execOptsLinux); const lines = res.toString().split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i] && lines[i][0] !== ' ') { if (pathToIp) { let nextline = lines[i + 1].trim().split(' '); if (nextline[0] === 'link/ether') { iface = lines[i].split(' ')[1]; iface = iface.slice(0, iface.length - 1); mac = nextline[1]; } } else { iface = lines[i].split(' ')[0]; mac = lines[i].split('HWaddr ')[1]; } if (iface && mac) { result[iface] = mac.trim(); iface = ''; mac = ''; } } } } catch (e) { util.noop(); } } if (_darwin) { try { const cmd = '/sbin/ifconfig'; let res = execSync(cmd); const lines = res.toString().split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i] && lines[i][0] !== '\t' && lines[i].indexOf(':') > 0) { iface = lines[i].split(':')[0]; } else if (lines[i].indexOf('\tether ') === 0) { mac = lines[i].split('\tether ')[1]; if (iface && mac) { result[iface] = mac.trim(); iface = ''; mac = ''; } } } } catch (e) { util.noop(); } } return result; } function networkInterfaceDefault(callback) { return new Promise((resolve) => { process.nextTick(() => { let result = getDefaultNetworkInterface(); if (callback) { callback(result); } resolve(result); }); }); } exports.networkInterfaceDefault = networkInterfaceDefault; // -------------------------- // NET - interfaces function parseLinesWindowsNics(sections, nconfigsections) { let nics = []; for (let i in sections) { try { if ({}.hasOwnProperty.call(sections, i)) { if (sections[i].trim() !== '') { let lines = sections[i].trim().split('\r\n'); let linesNicConfig = null; try { linesNicConfig = nconfigsections && nconfigsections[i] ? nconfigsections[i].trim().split('\r\n') : []; } catch (e) { util.noop(); } let netEnabled = util.getValue(lines, 'NetEnabled', ':'); let adapterType = util.getValue(lines, 'AdapterTypeID', ':') === '9' ? 'wireless' : 'wired'; let ifacename = util.getValue(lines, 'Name', ':').replace(/\]/g, ')').replace(/\[/g, '('); let iface = util.getValue(lines, 'NetConnectionID', ':').replace(/\]/g, ')').replace(/\[/g, '('); if (ifacename.toLowerCase().indexOf('wi-fi') >= 0 || ifacename.toLowerCase().indexOf('wireless') >= 0) { adapterType = 'wireless'; } if (netEnabled !== '') { const speed = parseInt(util.getValue(lines, 'speed', ':').trim(), 10) / 1000000; nics.push({ mac: util.getValue(lines, 'MACAddress', ':').toLowerCase(), dhcp: util.getValue(linesNicConfig, 'dhcpEnabled', ':').toLowerCase() === 'true', name: ifacename, iface, netEnabled: netEnabled === 'TRUE', speed: isNaN(speed) ? null : speed, operstate: util.getValue(lines, 'NetConnectionStatus', ':') === '2' ? 'up' : 'down', type: adapterType }); } } } } catch (e) { util.noop(); } } return nics; } function getWindowsNics() { return new Promise((resolve) => { process.nextTick(() => { let cmd = 'Get-CimInstance Win32_NetworkAdapter | fl *' + '; echo \'#-#-#-#\';'; cmd += 'Get-CimInstance Win32_NetworkAdapterConfiguration | fl DHCPEnabled' + ''; try { util.powerShell(cmd).then((data) => { data = data.split('#-#-#-#'); const nsections = (data[0] || '').split(/\n\s*\n/); const nconfigsections = (data[1] || '').split(/\n\s*\n/); resolve(parseLinesWindowsNics(nsections, nconfigsections)); }); } catch (e) { resolve([]); } }); }); } function getWindowsDNSsuffixes() { let iface = {}; let dnsSuffixes = { primaryDNS: '', exitCode: 0, ifaces: [], }; try { const ipconfig = execSync('ipconfig /all', util.execOptsWin); const ipconfigArray = ipconfig.split('\r\n\r\n'); ipconfigArray.forEach((element, index) => { if (index == 1) { const longPrimaryDNS = element.split('\r\n').filter((element) => { return element.toUpperCase().includes('DNS'); }); const primaryDNS = longPrimaryDNS[0].substring(longPrimaryDNS[0].lastIndexOf(':') + 1); dnsSuffixes.primaryDNS = primaryDNS.trim(); if (!dnsSuffixes.primaryDNS) { dnsSuffixes.primaryDNS = 'Not defined'; } } if (index > 1) { if (index % 2 == 0) { const name = element.substring(element.lastIndexOf(' ') + 1).replace(':', ''); iface.name = name; } else { const connectionSpecificDNS = element.split('\r\n').filter((element) => { return element.toUpperCase().includes('DNS'); }); const dnsSuffix = connectionSpecificDNS[0].substring(connectionSpecificDNS[0].lastIndexOf(':') + 1); iface.dnsSuffix = dnsSuffix.trim(); dnsSuffixes.ifaces.push(iface); iface = {}; } } }); return dnsSuffixes; } catch (error) { return { primaryDNS: '', exitCode: 0, ifaces: [], }; } } function getWindowsIfaceDNSsuffix(ifaces, ifacename) { let dnsSuffix = ''; // Adding (.) to ensure ifacename compatibility when duplicated iface-names const interfaceName = ifacename + '.'; try { const connectionDnsSuffix = ifaces.filter((iface) => { return interfaceName.includes(iface.name + '.'); }).map((iface) => iface.dnsSuffix); if (connectionDnsSuffix[0]) { dnsSuffix = connectionDnsSuffix[0]; } if (!dnsSuffix) { dnsSuffix = ''; } return dnsSuffix; } catch (error) { return 'Unknown'; } } function getWindowsWiredProfilesInformation() { try { const result = execSync('netsh lan show profiles', util.execOptsWin); const profileList = result.split('\r\nProfile on interface'); return profileList; } catch (error) { if (error.status === 1 && error.stdout.includes('AutoConfig')) { return 'Disabled'; } return []; } } function getWindowsWirelessIfaceSSID(interfaceName) { try { const result = execSync(`netsh wlan show interface name="${interfaceName}" | findstr "SSID"`, util.execOptsWin); const SSID = result.split('\r\n').shift(); const parseSSID = SSID.split(':').pop().trim(); return parseSSID; } catch (error) { return 'Unknown'; } } function getWindowsIEEE8021x(connectionType, iface, ifaces) { let i8021x = { state: 'Unknown', protocol: 'Unknown', }; if (ifaces === 'Disabled') { i8021x.state = 'Disabled'; i8021x.protocol = 'Not defined'; return i8021x; } if (connectionType == 'wired' && ifaces.length > 0) { try { // Get 802.1x information by interface name const iface8021xInfo = ifaces.find((element) => { return element.includes(iface + '\r\n'); }); const arrayIface8021xInfo = iface8021xInfo.split('\r\n'); const state8021x = arrayIface8021xInfo.find((element) => { return element.includes('802.1x'); }); if (state8021x.includes('Disabled')) { i8021x.state = 'Disabled'; i8021x.protocol = 'Not defined'; } else if (state8021x.includes('Enabled')) { const protocol8021x = arrayIface8021xInfo.find((element) => { return element.includes('EAP'); }); i8021x.protocol = protocol8021x.split(':').pop(); i8021x.state = 'Enabled'; } } catch (error) { return i8021x; } } else if (connectionType == 'wireless') { let i8021xState = ''; let i8021xProtocol = ''; try { const SSID = getWindowsWirelessIfaceSSID(iface); if (SSID !== 'Unknown') { let ifaceSanitized = ''; const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(SSID); const l = util.mathMin(s.length, 32); for (let i = 0; i <= l; i++) { if (s[i] !== undefined) { ifaceSanitized = ifaceSanitized + s[i]; } } i8021xState = execSync(`netsh wlan show profiles "${ifaceSanitized}" | findstr "802.1X"`, util.execOptsWin); i8021xProtocol = execSync(`netsh wlan show profiles "${ifaceSanitized}" | findstr "EAP"`, util.execOptsWin); } if (i8021xState.includes(':') && i8021xProtocol.includes(':')) { i8021x.state = i8021xState.split(':').pop(); i8021x.protocol = i8021xProtocol.split(':').pop(); } } catch (error) { if (error.status === 1 && error.stdout.includes('AutoConfig')) { i8021x.state = 'Disabled'; i8021x.protocol = 'Not defined'; } return i8021x; } } return i8021x; } function splitSectionsNics(lines) { const result = []; let section = []; lines.forEach(function (line) { if (!line.startsWith('\t') && !line.startsWith(' ')) { if (section.length) { result.push(section); section = []; } } section.push(line); }); if (section.length) { result.push(section); } return result; } function parseLinesDarwinNics(sections) { let nics = []; sections.forEach(section => { let nic = { iface: '', mtu: null, mac: '', ip6: '', ip4: '', speed: null, type: '', operstate: '', duplex: '', internal: false }; const first = section[0]; nic.iface = first.split(':')[0].trim(); let parts = first.split('> mtu'); nic.mtu = parts.length > 1 ? parseInt(parts[1], 10) : null; if (isNaN(nic.mtu)) { nic.mtu = null; } nic.internal = parts[0].toLowerCase().indexOf('loopback') > -1; section.forEach(line => { if (line.trim().startsWith('ether ')) { nic.mac = line.split('ether ')[1].toLowerCase().trim(); } if (line.trim().startsWith('inet6 ') && !nic.ip6) { nic.ip6 = line.split('inet6 ')[1].toLowerCase().split('%')[0].split(' ')[0]; } if (line.trim().startsWith('inet ') && !nic.ip4) { nic.ip4 = line.split('inet ')[1].toLowerCase().split(' ')[0]; } }); let speed = util.getValue(section, 'link rate'); nic.speed = speed ? parseFloat(speed) : null; if (nic.speed === null) { speed = util.getValue(section, 'uplink rate'); nic.speed = speed ? parseFloat(speed) : null; if (nic.speed !== null && speed.toLowerCase().indexOf('gbps') >= 0) { nic.speed = nic.speed * 1000; } } else { if (speed.toLowerCase().indexOf('gbps') >= 0) { nic.speed = nic.speed * 1000; } } nic.type = util.getValue(section, 'type').toLowerCase().indexOf('wi-fi') > -1 ? 'wireless' : 'wired'; const operstate = util.getValue(section, 'status').toLowerCase(); nic.operstate = (operstate === 'active' ? 'up' : (operstate === 'inactive' ? 'down' : 'unknown')); nic.duplex = util.getValue(section, 'media').toLowerCase().indexOf('half-duplex') > -1 ? 'half' : 'full'; if (nic.ip6 || nic.ip4 || nic.mac) { nics.push(nic); } }); return nics; } function getDarwinNics() { const cmd = '/sbin/ifconfig -v'; try { const lines = execSync(cmd, { maxBuffer: 1024 * 20000 }).toString().split('\n'); const nsections = splitSectionsNics(lines); return (parseLinesDarwinNics(nsections)); } catch (e) { return []; } } function getLinuxIfaceConnectionName(interfaceName) { const cmd = `nmcli device status 2>/dev/null | grep ${interfaceName}`; try { const result = execSync(cmd, util.execOptsLinux).toString(); const resultFormat = result.replace(/\s+/g, ' ').trim(); const connectionNameLines = resultFormat.split(' ').slice(3); const connectionName = connectionNameLines.join(' '); return connectionName != '--' ? connectionName : ''; } catch (e) { return ''; } } function checkLinuxDCHPInterfaces(file) { let result = []; try { let cmd = `cat ${file} 2> /dev/null | grep 'iface\\|source'`; const lines = execSync(cmd, util.execOptsLinux).toString().split('\n'); lines.forEach(line => { const parts = line.replace(/\s+/g, ' ').trim().split(' '); if (parts.length >= 4) { if (line.toLowerCase().indexOf(' inet ') >= 0 && line.toLowerCase().indexOf('dhcp') >= 0) { result.push(parts[1]); } } if (line.toLowerCase().includes('source')) { let file = line.split(' ')[1]; result = result.concat(checkLinuxDCHPInterfaces(file)); } }); } catch (e) { util.noop(); } return result; } function getLinuxDHCPNics() { // alternate methods getting interfaces using DHCP let cmd = 'ip a 2> /dev/null'; let result = []; try { const lines = execSync(cmd, util.execOptsLinux).toString().split('\n'); const nsections = splitSectionsNics(lines); result = (parseLinuxDHCPNics(nsections)); } catch (e) { util.noop(); } try { result = checkLinuxDCHPInterfaces('/etc/network/interfaces'); } catch (e) { util.noop(); } return result; } function parseLinuxDHCPNics(sections) { const result = []; if (sections && sections.length) { sections.forEach(lines => { if (lines && lines.length) { const parts = lines[0].split(':'); if (parts.length > 2) { for (let line of lines) { if (line.indexOf(' inet ') >= 0 && line.indexOf(' dynamic ') >= 0) { const parts2 = line.split(' '); const nic = parts2[parts2.length - 1].trim(); result.push(nic); break; } } } } }); } return result; } function getLinuxIfaceDHCPstatus(iface, connectionName, DHCPNics) { let result = false; if (connectionName) { const cmd = `nmcli connection show "${connectionName}" 2>/dev/null | grep ipv4.method;`; try { const lines = execSync(cmd, util.execOptsLinux).toString(); const resultFormat = lines.replace(/\s+/g, ' ').trim(); let dhcStatus = resultFormat.split(' ').slice(1).toString(); switch (dhcStatus) { case 'auto': result = true; break; default: result = false; break; } return result; } catch (e) { return (DHCPNics.indexOf(iface) >= 0); } } else { return (DHCPNics.indexOf(iface) >= 0); } } function getDarwinIfaceDHCPstatus(iface) { let result = false; const cmd = `ipconfig getpacket "${iface}" 2>/dev/null | grep lease_time;`; try { const lines = execSync(cmd).toString().split('\n'); if (lines.length && lines[0].startsWith('lease_time')) { result = true; } } catch (e) { util.noop(); } return result; } function getLinuxIfaceDNSsuffix(connectionName) { if (connectionName) { const cmd = `nmcli connection show "${connectionName}" 2>/dev/null | grep ipv4.dns-search;`; try { const result = execSync(cmd, util.execOptsLinux).toString(); const resultFormat = result.replace(/\s+/g, ' ').trim(); const dnsSuffix = resultFormat.split(' ').slice(1).toString(); return dnsSuffix == '--' ? 'Not defined' : dnsSuffix; } catch (e) { return 'Unknown'; } } else { return 'Unknown'; } } function getLinuxIfaceIEEE8021xAuth(connectionName) { if (connectionName) { const cmd = `nmcli connection show "${connectionName}" 2>/dev/null | grep 802-1x.eap;`; try { const result = execSync(cmd, util.execOptsLinux).toString(); const resultFormat = result.replace(/\s+/g, ' ').trim(); const authenticationProtocol = resultFormat.split(' ').slice(1).toString(); return authenticationProtocol == '--' ? '' : authenticationProtocol; } catch (e) { return 'Not defined'; } } else { return 'Not defined'; } } function getLinuxIfaceIEEE8021xState(authenticationProtocol) { if (authenticationProtocol) { if (authenticationProtocol == 'Not defined') { return 'Disabled'; } return 'Enabled'; } else { return 'Unknown'; } } function testVirtualNic(iface, ifaceName, mac) { const virtualMacs = ['00:00:00:00:00:00', '00:03:FF', '00:05:69', '00:0C:29', '00:0F:4B', '00:13:07', '00:13:BE', '00:15:5d', '00:16:3E', '00:1C:42', '00:21:F6', '00:24:0B', '00:50:56', '00:A0:B1', '00:E0:C8', '08:00:27', '0A:00:27', '18:92:2C', '16:DF:49', '3C:F3:92', '54:52:00', 'FC:15:97']; if (mac) { return virtualMacs.filter(item => { return mac.toUpperCase().toUpperCase().startsWith(item.substring(0, mac.length)); }).length > 0 || iface.toLowerCase().indexOf(' virtual ') > -1 || ifaceName.toLowerCase().indexOf(' virtual ') > -1 || iface.toLowerCase().indexOf('vethernet ') > -1 || ifaceName.toLowerCase().indexOf('vethernet ') > -1 || iface.toLowerCase().startsWith('veth') || ifaceName.toLowerCase().startsWith('veth') || iface.toLowerCase().startsWith('vboxnet') || ifaceName.toLowerCase().startsWith('vboxnet'); } else { return false; } } function networkInterfaces(callback, rescan, defaultString) { if (typeof callback === 'string') { defaultString = callback; rescan = true; callback = null; } if (typeof callback === 'boolean') { rescan = callback; callback = null; defaultString = ''; } if (typeof rescan === 'undefined') { rescan = true; } defaultString = defaultString || ''; defaultString = '' + defaultString; return new Promise((resolve) => { process.nextTick(() => { let ifaces = os.networkInterfaces(); let result = []; let nics = []; let dnsSuffixes = []; let nics8021xInfo = []; // seperate handling in OSX if (_darwin || _freebsd || _openbsd || _netbsd) { if ((JSON.stringify(ifaces) === JSON.stringify(_ifaces)) && !rescan) { // no changes - just return object result = _networkInterfaces; if (callback) { callback(result); } resolve(result); } else { const defaultInterface = getDefaultNetworkInterface(); _ifaces = JSON.parse(JSON.stringify(ifaces)); nics = getDarwinNics(); nics.forEach(nic => { if ({}.hasOwnProperty.call(ifaces, nic.iface)) { ifaces[nic.iface].forEach(function (details) { if (details.family === 'IPv4' || details.family === 4) { nic.ip4subnet = details.netmask; } if (details.family === 'IPv6' || details.family === 6) { nic.ip6subnet = details.netmask; } }); } let ifaceSanitized = ''; const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(nic.iface); const l = util.mathMin(s.length, 2000); for (let i = 0; i <= l; i++) { if (s[i] !== undefined) { ifaceSanitized = ifaceSanitized + s[i]; } } result.push({ iface: nic.iface, ifaceName: nic.iface, default: nic.iface === defaultInterface, ip4: nic.ip4, ip4subnet: nic.ip4subnet || '', ip6: nic.ip6, ip6subnet: nic.ip6subnet || '', mac: nic.mac, internal: nic.internal, virtual: nic.internal ? false : testVirtualNic(nic.iface, nic.iface, nic.mac), operstate: nic.operstate, type: nic.type, duplex: nic.duplex, mtu: nic.mtu, speed: nic.speed, dhcp: getDarwinIfaceDHCPstatus(ifaceSanitized), dnsSuffix: '', ieee8021xAuth: '', ieee8021xState: '', carrierChanges: 0 }); }); _networkInterfaces = result; if (defaultString.toLowerCase().indexOf('default') >= 0) { result = result.filter(item => item.default); if (result.length > 0) { result = result[0]; } else { result = []; } } if (callback) { callback(result); } resolve(result); } } if (_linux) { if ((JSON.stringify(ifaces) === JSON.stringify(_ifaces)) && !rescan) { // no changes - just return object result = _networkInterfaces; if (callback) { callback(result); } resolve(result); } else { _ifaces = JSON.parse(JSON.stringify(ifaces)); _dhcpNics = getLinuxDHCPNics(); const defaultInterface = getDefaultNetworkInterface(); for (let dev in ifaces) { let ip4 = ''; let ip4subnet = ''; let ip6 = ''; let ip6subnet = ''; let mac = ''; let duplex = ''; let mtu = ''; let speed = null; let carrierChanges = 0; let dhcp = false; let dnsSuffix = ''; let ieee8021xAuth = ''; let ieee8021xState = ''; let type = ''; if ({}.hasOwnProperty.call(ifaces, dev)) { let ifaceName = dev; ifaces[dev].forEach(function (details) { if (details.family === 'IPv4' || details.family === 4) { ip4 = details.address; ip4subnet = details.netmask; } if (details.family === 'IPv6' || details.family === 6) { if (!ip6 || ip6.match(/^fe80::/i)) { ip6 = details.address; ip6subnet = details.netmask; } } mac = details.mac; // fallback due to https://github.com/nodejs/node/issues/13581 (node 8.1 - node 8.2) const nodeMainVersion = parseInt(process.versions.node.split('.'), 10); if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin) && (!details.internal) && nodeMainVersion >= 8 && nodeMainVersion <= 11) { if (Object.keys(_mac).length === 0) { _mac = getMacAddresses(); } mac = _mac[dev] || ''; } }); let iface = dev.split(':')[0].trim().toLowerCase(); let ifaceSanitized = ''; const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(iface); const l = util.mathMin(s.length, 2000); for (let i = 0; i <= l; i++) { if (s[i] !== undefined) { ifaceSanitized = ifaceSanitized + s[i]; } } const cmd = `echo -n "addr_assign_type: "; cat /sys/class/net/${ifaceSanitized}/addr_assign_type 2>/dev/null; echo; echo -n "address: "; cat /sys/class/net/${ifaceSanitized}/address 2>/dev/null; echo; echo -n "addr_len: "; cat /sys/class/net/${ifaceSanitized}/addr_len 2>/dev/null; echo; echo -n "broadcast: "; cat /sys/class/net/${ifaceSanitized}/broadcast 2>/dev/null; echo; echo -n "carrier: "; cat /sys/class/net/${ifaceSanitized}/carrier 2>/dev/null; echo; echo -n "carrier_changes: "; cat /sys/class/net/${ifaceSanitized}/carrier_changes 2>/dev/null; echo; echo -n "dev_id: "; cat /sys/class/net/${ifaceSanitized}/dev_id 2>/dev/null; echo; echo -n "dev_port: "; cat /sys/class/net/${ifaceSanitized}/dev_port 2>/dev/null; echo; echo -n "dormant: "; cat /sys/class/net/${ifaceSanitized}/dormant 2>/dev/null; echo; echo -n "duplex: "; cat /sys/class/net/${ifaceSanitized}/duplex 2>/dev/null; echo; echo -n "flags: "; cat /sys/class/net/${ifaceSanitized}/flags 2>/dev/null; echo; echo -n "gro_flush_timeout: "; cat /sys/class/net/${ifaceSanitized}/gro_flush_timeout 2>/dev/null; echo; echo -n "ifalias: "; cat /sys/class/net/${ifaceSanitized}/ifalias 2>/dev/null; echo; echo -n "ifindex: "; cat /sys/class/net/${ifaceSanitized}/ifindex 2>/dev/null; echo; echo -n "iflink: "; cat /sys/class/net/${ifaceSanitized}/iflink 2>/dev/null; echo; echo -n "link_mode: "; cat /sys/class/net/${ifaceSanitized}/link_mode 2>/dev/null; echo; echo -n "mtu: "; cat /sys/class/net/${ifaceSanitized}/mtu 2>/dev/null; echo; echo -n "netdev_group: "; cat /sys/class/net/${ifaceSanitized}/netdev_group 2>/dev/null; echo; echo -n "operstate: "; cat /sys/class/net/${ifaceSanitized}/operstate 2>/dev/null; echo; echo -n "proto_down: "; cat /sys/class/net/${ifaceSanitized}/proto_down 2>/dev/null; echo; echo -n "speed: "; cat /sys/class/net/${ifaceSanitized}/speed 2>/dev/null; echo; echo -n "tx_queue_len: "; cat /sys/class/net/${ifaceSanitized}/tx_queue_len 2>/dev/null; echo; echo -n "type: "; cat /sys/class/net/${ifaceSanitized}/type 2>/dev/null; echo; echo -n "wireless: "; cat /proc/net/wireless 2>/dev/null | grep ${ifaceSanitized}; echo; echo -n "wirelessspeed: "; iw dev ${ifaceSanitized} link 2>&1 | grep bitrate; echo;`; let lines = []; try { lines = execSync(cmd, util.execOptsLinux).toString().split('\n'); const connectionName = getLinuxIfaceConnectionName(ifaceSanitized); dhcp = getLinuxIfaceDHCPstatus(ifaceSanitized, connectionName, _dhcpNics); dnsSuffix = getLinuxIfaceDNSsuffix(connectionName); ieee8021xAuth = getLinuxIfaceIEEE8021xAuth(connectionName); ieee8021xState = getLinuxIfaceIEEE8021xState(ieee8021xAuth); } catch (e) { util.noop(); } duplex = util.getValue(lines, 'duplex'); duplex = duplex.startsWith('cat') ? '' : duplex; mtu = parseInt(util.getValue(lines, 'mtu'), 10); let myspeed = parseInt(util.getValue(lines, 'speed'), 10); speed = isNaN(myspeed) ? null : myspeed; let wirelessspeed = util.getValue(lines, 'wirelessspeed').split('tx bitrate: '); if (speed === null && wirelessspeed.length === 2) { myspeed = parseFloat(wirelessspeed[1]); speed = isNaN(myspeed) ? null : myspeed; } carrierChanges = parseInt(util.getValue(lines, 'carrier_changes'), 10); const operstate = util.getValue(lines, 'operstate'); type = operstate === 'up' ? (util.getValue(lines, 'wireless').trim() ? 'wireless' : 'wired') : 'unknown'; if (ifaceSanitized === 'lo' || ifaceSanitized.startsWith('bond')) { type = 'virtual'; } let internal = (ifaces[dev] && ifaces[dev][0]) ? ifaces[dev][0].internal : false; if (dev.toLowerCase().indexOf('loopback') > -1 || ifaceName.toLowerCase().indexOf('loopback') > -1) { internal = true; } const virtual = internal ? false : testVirtualNic(dev, ifaceName, mac); result.push({ iface: ifaceSanitized, ifaceName, default: iface === defaultInterface, ip4, ip4subnet, ip6, ip6subnet, mac, internal, virtual, operstate, type, duplex, mtu, speed, dhcp, dnsSuffix, ieee8021xAuth, ieee8021xState, carrierChanges, }); } } _networkInterfaces = result; if (defaultString.toLowerCase().indexOf('default') >= 0) { result = result.filter(item => item.default); if (result.length > 0) { result = result[0]; } else { result = []; } } if (callback) { callback(result); } resolve(result); } } if (_windows) { if ((JSON.stringify(ifaces) === JSON.stringify(_ifaces)) && !rescan) { // no changes - just return object result = _networkInterfaces; if (callback) { callback(result); } resolve(result); } else { _ifaces = JSON.parse(JSON.stringify(ifaces)); const defaultInterface = getDefaultNetworkInterface(); getWindowsNics().then(function (nics) { nics.forEach(nic => { let found = false; Object.keys(ifaces).forEach(key => { if (!found) { ifaces[key].forEach(value => { if (Object.keys(value).indexOf('mac') >= 0) { found = value['mac'] === nic.mac; } }); } }); if (!found) { ifaces[nic.name] = [{ mac: nic.mac }]; } }); nics8021xInfo = getWindowsWiredProfilesInformation(); dnsSuffixes = getWindowsDNSsuffixes(); for (let dev in ifaces) { let ifaceSanitized = ''; const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(dev); const l = util.mathMin(s.length, 2000); for (let i = 0; i <= l; i++) { if (s[i] !== undefined) { ifaceSanitized = ifaceSanitized + s[i]; } } let iface = dev; let ip4 = ''; let ip4subnet = ''; let ip6 = ''; let ip6subnet = ''; let mac = ''; let duplex = ''; let mtu = ''; let speed = null; let carrierChanges = 0; let operstate = 'down'; let dhcp = false; let dnsSuffix = ''; let ieee8021xAuth = ''; let ieee8021xState = ''; let type = ''; if ({}.hasOwnProperty.call(ifaces, dev)) { let ifaceName = dev; ifaces[dev].forEach(function (details) { if (details.family === 'IPv4' || details.family === 4) { ip4 = details.address; ip4subnet = details.netmask; } if (details.family === 'IPv6' || details.family === 6) { if (!ip6 || ip6.match(/^fe80::/i)) { ip6 = details.address; ip6subnet = details.netmask; } } mac = details.mac; // fallback due to https://github.com/nodejs/node/issues/13581 (node 8.1 - node 8.2) const nodeMainVersion = parseInt(process.versions.node.split('.'), 10); if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin) && (!details.internal) && nodeMainVersion >= 8 && nodeMainVersion <= 11) { if (Object.keys(_mac).length === 0) { _mac = getMacAddresses(); } mac = _mac[dev] || ''; } }); dnsSuffix = getWindowsIfaceDNSsuffix(dnsSuffixes.ifaces, ifaceSanitized); let foundFirst = false; nics.forEach(detail => { if (detail.mac === mac && !foundFirst) { iface = detail.iface || iface; ifaceName = detail.name; dhcp = detail.dhcp; operstate = detail.operstate; speed = operstate === 'up' ? detail.speed : 0; type = detail.type; foundFirst = true; } }); if (dev.toLowerCase().indexOf('wlan') >= 0 || ifaceName.toLowerCase().indexOf('wlan') >= 0 || ifaceName.toLowerCase().indexOf('802.11n') >= 0 || ifaceName.toLowerCase().indexOf('wireless') >= 0 || ifaceName.toLowerCase().indexOf('wi-fi') >= 0 || ifaceName.toLowerCase().indexOf('wifi') >= 0) { type = 'wireless'; } const IEEE8021x = getWindowsIEEE8021x(type, ifaceSanitized, nics8021xInfo); ieee8021xAuth = IEEE8021x.protocol; ieee8021xState = IEEE8021x.state; let internal = (ifaces[dev] && ifaces[dev][0]) ? ifaces[dev][0].internal : false; if (dev.toLowerCase().indexOf('loopback') > -1 || ifaceName.toLowerCase().indexOf('loopback') > -1) { internal = true; } const virtual = internal ? false : testVirtualNic(dev, ifaceName, mac); result.push({ iface, ifaceName, default: iface === defaultInterface, ip4, ip4subnet, ip6, ip6subnet, mac, internal, virtual, operstate, type, duplex, mtu, speed, dhcp, dnsSuffix, ieee8021xAuth, ieee8021xState, carrierChanges, }); } } _networkInterfaces = result; if (defaultString.toLowerCase().indexOf('default') >= 0) { result = result.filter(item => item.default); if (result.length > 0) { result = result[0]; } else { result = []; } } if (callback) { callback(result); } resolve(result); }); } } }); }); } exports.networkInterfaces = networkInterfaces; // -------------------------- // NET - Speed function calcNetworkSpeed(iface, rx_bytes, tx_bytes, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors) { let result = { iface, operstate, rx_bytes, rx_dropped, rx_errors, tx_bytes, tx_dropped, tx_errors, rx_sec: null, tx_sec: null, ms: 0 }; if (_network[iface] && _network[iface].ms) { result.ms = Date.now() - _network[iface].ms; result.rx_sec = (rx_bytes - _network[iface].rx_bytes) >= 0 ? (rx_bytes - _network[iface].rx_bytes) / (result.ms / 1000) : 0; result.tx_sec = (tx_bytes - _network[iface].tx_bytes) >= 0 ? (tx_bytes - _network[iface].tx_bytes) / (result.ms / 1000) : 0; _network[iface].rx_bytes = rx_bytes; _network[iface].tx_bytes = tx_bytes; _network[iface].rx_sec = result.rx_sec; _network[iface].tx_sec = result.tx_sec; _network[iface].ms = Date.now(); _network[iface].last_ms = result.ms; _network[iface].operstate = operstate; } else { if (!_network[iface]) { _network[iface] = {}; } _network[iface].rx_bytes = rx_bytes; _network[iface].tx_bytes = tx_bytes; _network[iface].rx_sec = null; _network[iface].tx_sec = null; _network[iface].ms = Date.now(); _network[iface].last_ms = 0; _network[iface].operstate = operstate; } return result; } function networkStats(ifaces, callback) { let ifacesArray = []; return new Promise((resolve) => { process.nextTick(() => { // fallback - if only callback is given if (util.isFunction(ifaces) && !callback) { callback = ifaces; ifacesArray = [getDefaultNetworkInterface()]; } else { if (typeof ifaces !== 'string' && ifaces !== undefined) { if (callback) { callback([]); } return resolve([]); } ifaces = ifaces || getDefaultNetworkInterface(); try { ifaces.__proto__.toLowerCase = util.stringToLower; ifaces.__proto__.replace = util.stringReplace; ifaces.__proto__.toString = util.stringToString; ifaces.__proto__.substr = util.stringSubstr; ifaces.__proto__.substring = util.stringSubstring; ifaces.__proto__.trim = util.stringTrim; ifaces.__proto__.startsWith = util.stringStartWith; } catch (e) { Object.setPrototypeOf(ifaces, util.stringObj); } ifaces = ifaces.trim().toLowerCase().replace(/,+/g, '|'); ifacesArray = ifaces.split('|'); } const result = []; const workload = []; if (ifacesArray.length && ifacesArray[0].trim() === '*') { ifacesArray = []; networkInterfaces(false).then(allIFaces => { for (let iface of allIFaces) { ifacesArray.push(iface.iface); } networkStats(ifacesArray.join(',')).then(result => { if (callback) { callback(result); } resolve(result); }); }); } else { for (let iface of ifacesArray) { workload.push(networkStatsSingle(iface.trim())); } if (workload.length) { Promise.all( workload ).then((data) => { if (callback) { callback(data); } resolve(data); }); } else { if (callback) { callback(result); } resolve(result); } } }); }); } function networkStatsSingle(iface) { function parseLinesWindowsPerfData(sections) { let perfData = []; for (let i in sections) { if ({}.hasOwnProperty.call(sections, i)) { if (sections[i].trim() !== '') { let lines = sections[i].trim().split('\r\n'); perfData.push({ name: util.getValue(lines, 'Name', ':').replace(/[()[\] ]+/g, '').replace(/#|\//g, '_').toLowerCase(), rx_bytes: parseInt(util.getValue(lines, 'BytesReceivedPersec', ':'), 10), rx_errors: parseInt(util.getValue(lines, 'PacketsReceivedErrors', ':'), 10), rx_dropped: parseInt(util.getValue(lines, 'PacketsReceivedDiscarded', ':'), 10), tx_bytes: parseInt(util.getValue(lines, 'BytesSentPersec', ':'), 10), tx_errors: parseInt(util.getValue(lines, 'PacketsOutboundErrors', ':'), 10), tx_dropped: parseInt(util.getValue(lines, 'PacketsOutboundDiscarded', ':'), 10) }); } } } return perfData; } return new Promise((resolve) => { process.nextTick(() => { let ifaceSanitized = ''; const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(iface); const l = util.mathMin(s.length, 2000); for (let i = 0; i <= l; i++) { if (s[i] !== undefined) { ifaceSanitized = ifaceSanitized + s[i]; } } let result = { iface: ifaceSanitized, operstate: 'unknown', rx_bytes: 0, rx_dropped: 0, rx_errors: 0, tx_bytes: 0, tx_dropped: 0, tx_errors: 0, rx_sec: null, tx_sec: null, ms: 0 }; let operstate = 'unknown'; let rx_bytes = 0; let tx_bytes = 0; let rx_dropped = 0; let rx_errors = 0; let tx_dropped = 0; let tx_errors = 0; let cmd, lines, stats; if (!_network[ifaceSanitized] || (_network[ifaceSanitized] && !_network[ifaceSanitized].ms) || (_network[ifaceSanitized] && _network[ifaceSanitized].ms && Date.now() - _network[ifaceSanitized].ms >= 500)) { if (_linux) { if (fs.existsSync('/sys/class/net/' + ifaceSanitized)) { cmd = 'cat /sys/class/net/' + ifaceSanitized + '/operstate; ' + 'cat /sys/class/net/' + ifaceSanitized + '/statistics/rx_bytes; ' + 'cat /sys/class/net/' + ifaceSanitized + '/statistics/tx_bytes; ' + 'cat /sys/class/net/' + ifaceSanitized + '/statistics/rx_dropped; ' + 'cat /sys/class/net/' + ifaceSanitized + '/statistics/rx_errors; ' + 'cat /sys/class/net/' + ifaceSanitized + '/statistics/tx_dropped; ' + 'cat /sys/class/net/' + ifaceSanitized + '/statistics/tx_errors; '; exec(cmd, function (error, stdout) { if (!error) { lines = stdout.toString().split('\n'); operstate = lines[0].trim(); rx_bytes = parseInt(lines[1], 10); tx_bytes = parseInt(lines[2], 10); rx_dropped = parseInt(lines[3], 10); rx_errors = parseInt(lines[4], 10); tx_dropped = parseInt(lines[5], 10); tx_errors = parseInt(lines[6], 10); result = calcNetworkSpeed(ifaceSanitized, rx_bytes, tx_bytes, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors); } resolve(result); }); } else { resolve(result); } } if (_freebsd || _openbsd || _netbsd) { cmd = 'netstat -ibndI ' + ifaceSanitized; // lgtm [js/shell-command-constructed-from-input] exec(cmd, function (error, stdout) { if (!error) { lines = stdout.toString().split('\n'); for (let i = 1; i < lines.length; i++) { const line = lines[i].replace(/ +/g, ' ').split(' '); if (line && line[0] && line[7] && line[10]) { rx_bytes = rx_bytes + parseInt(line[7]); if (line[6].trim() !== '-') { rx_dropped = rx_dropped + parseInt(line[6]); } if (line[5].trim() !== '-') { rx_errors = rx_errors + parseInt(line[5]); } tx_bytes = tx_bytes + parseInt(line[10]); if (line[12].trim() !== '-') { tx_dropped = tx_dropped + parseInt(line[12]); } if (line[9].trim() !== '-') { tx_errors = tx_errors + parseInt(line[9]); } operstate = 'up'; } } result = calcNetworkSpeed(ifaceSanitized, rx_bytes, tx_bytes, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors); } resolve(result); }); } if (_darwin) { cmd = 'ifconfig ' + ifaceSanitized + ' | grep "status"'; // lgtm [js/shell-command-constructed-from-input] exec(cmd, function (error, stdout) { result.operstate = (stdout.toString().split(':')[1] || '').trim(); result.operstate = (result.operstate || '').toLowerCase(); result.operstate = (result.operstate === 'active' ? 'up' : (result.operstate === 'inactive' ? 'down' : 'unknown')); cmd = 'netstat -bdI ' + ifaceSanitized; // lgtm [js/shell-command-constructed-from-input] exec(cmd, function (error, stdout) { if (!error) { lines = stdout.toString().split('\n'); // if there is less than 2 lines, no information for this interface was found if (lines.length > 1 && lines[1].trim() !== '') { // skip header line // use the second line because it is tied to the NIC instead of the ipv4 or ipv6 address stats = lines[1].replace(/ +/g, ' ').split(' '); const offset = stats.length > 11 ? 1 : 0; rx_bytes = parseInt(stats[offset + 5]); rx_dropped = parseInt(stats[offset + 10]); rx_errors = parseInt(stats[offset + 4]); tx_bytes = parseInt(stats[offset + 8]); tx_dropped = parseInt(stats[offset + 10]); tx_errors = parseInt(stats[offset + 7]); result = calcNetworkSpeed(ifaceSanitized, rx_bytes, tx_bytes, result.operstate, rx_dropped, rx_errors, tx_dropped, tx_errors); } } resolve(result); }); }); } if (_windows) { let perfData = []; let ifaceName = ifaceSanitized; // Performance Data util.powerShell('Get-CimInstance Win32_PerfRawData_Tcpip_NetworkInterface | select Name,BytesReceivedPersec,PacketsReceivedErrors,PacketsReceivedDiscarded,BytesSentPersec,PacketsOutboundErrors,PacketsOutboundDiscarded | fl').then((stdout, error) => { if (!error) { const psections = stdout.toString().split(/\n\s*\n/); perfData = parseLinesWindowsPerfData(psections); } // Network Interfaces networkInterfaces(false).then(interfaces => { // get bytes sent, received from perfData by name rx_bytes = 0; tx_bytes = 0; perfData.forEach(detail => { interfaces.forEach(det => { if ((det.iface.toLowerCase() === ifaceSanitized.toLowerCase() || det.mac.toLowerCase() === ifaceSanitized.toLowerCase() || det.ip4.toLowerCase() === ifaceSanitized.toLowerCase() || det.ip6.toLowerCase() === ifaceSanitized.toLowerCase() || det.ifaceName.replace(/[()[\] ]+/g, '').replace(/#|\//g, '_').toLowerCase() === ifaceSanitized.replace(/[()[\] ]+/g, '').replace('#', '_').toLowerCase()) && (det.ifaceName.replace(/[()[\] ]+/g, '').replace(/#|\//g, '_').toLowerCase() === detail.name)) { ifaceName = det.iface; rx_bytes = detail.rx_bytes; rx_dropped = detail.rx_dropped; rx_errors = detail.rx_errors; tx_bytes = detail.tx_bytes; tx_dropped = detail.tx_dropped; tx_errors = detail.tx_errors; operstate = det.operstate; } }); }); if (rx_bytes && tx_bytes) { result = calcNetworkSpeed(ifaceName, parseInt(rx_bytes), parseInt(tx_bytes), operstate, rx_dropped, rx_errors, tx_dropped, tx_errors); } resolve(result); }); }); } } else { result.rx_bytes = _network[ifaceSanitized].rx_bytes; result.tx_bytes = _network[ifaceSanitized].tx_bytes; result.rx_sec = _network[ifaceSanitized].rx_sec; result.tx_sec = _network[ifaceSanitized].tx_sec; result.ms = _network[ifaceSanitized].last_ms; result.operstate = _network[ifaceSanitized].operstate; resolve(result); } }); }); } exports.networkStats = networkStats; // -------------------------- // NET - connections (sockets) function getProcessName(processes, pid) { let cmd = ''; processes.forEach(line => { const parts = line.split(' '); const id = parseInt(parts[0], 10) || -1; if (id === pid) { parts.shift(); cmd = parts.join(' ').split(':')[0]; } }); cmd = cmd.split(' -')[0]; cmd = cmd.split(' /')[0]; return cmd; // const cmdParts = cmd.split('/'); // return cmdParts[cmdParts.length - 1]; } function networkConnections(callback) { return new Promise((resolve) => { process.nextTick(() => { let result = []; if (_linux || _freebsd || _openbsd || _netbsd) { let cmd = 'export LC_ALL=C; netstat -tunap | grep "ESTABLISHED\\|SYN_SENT\\|SYN_RECV\\|FIN_WAIT1\\|FIN_WAIT2\\|TIME_WAIT\\|CLOSE\\|CLOSE_WAIT\\|LAST_ACK\\|LISTEN\\|CLOSING\\|UNKNOWN"; unset LC_ALL'; if (_freebsd || _openbsd || _netbsd) { cmd = 'export LC_ALL=C; netstat -na | grep "ESTABLISHED\\|SYN_SENT\\|SYN_RECV\\|FIN_WAIT1\\|FIN_WAIT2\\|TIME_WAIT\\|CLOSE\\|CLOSE_WAIT\\|LAST_ACK\\|LISTEN\\|CLOSING\\|UNKNOWN"; unset LC_ALL'; } exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) { let lines = stdout.toString().split('\n'); if (!error && (lines.length > 1 || lines[0] != '')) { lines.forEach(function (line) { line = line.replace(/ +/g, ' ').split(' '); if (line.length >= 7) { let localip = line[3]; let localport = ''; let localaddress = line[3].split(':'); if (localaddress.length > 1) { localport = localaddress[localaddress.length - 1]; localaddress.pop(); localip = localaddress.join(':'); } let peerip = line[4]; let peerport = ''; let peeraddress = line[4].split(':'); if (peeraddress.length > 1) { peerport = peeraddress[peeraddress.length - 1]; peeraddress.pop(); peerip = peeraddress.join(':'); } let connstate = line[5]; let proc = line[6].split('/'); if (connstate) { result.push({ protocol: line[0], localAddress: localip, localPort: localport, peerAddress: peerip, peerPort: peerport, state: connstate, pid: proc[0] && proc[0] !== '-' ? parseInt(proc[0], 10) : null, process: proc[1] ? proc[1].split(' ')[0].split(':')[0] : '' }); } } }); if (callback) { callback(result); } resolve(result); } else { cmd = 'ss -tunap | grep "ESTAB\\|SYN-SENT\\|SYN-RECV\\|FIN-WAIT1\\|FIN-WAIT2\\|TIME-WAIT\\|CLOSE\\|CLOSE-WAIT\\|LAST-ACK\\|LISTEN\\|CLOSING"'; exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) { if (!error) { let lines = stdout.toString().split('\n'); lines.forEach(function (line) { line = line.replace(/ +/g, ' ').split(' '); if (line.length >= 6) { let localip = line[4]; let localport = ''; let localaddress = line[4].split(':'); if (localaddress.length > 1) { localport = localaddress[localaddress.length - 1]; localaddress.pop(); localip = localaddress.join(':'); } let peerip = line[5]; let peerport = ''; let peeraddress = line[5].split(':'); if (peeraddress.length > 1) { peerport = peeraddress[peeraddress.length - 1]; peeraddress.pop(); peerip = peeraddress.join(':'); } let connstate = line[1]; if (connstate === 'ESTAB') { connstate = 'ESTABLISHED'; } if (connstate === 'TIME-WAIT') { connstate = 'TIME_WAIT'; } let pid = null; let process = ''; if (line.length >= 7 && line[6].indexOf('users:') > -1) { let proc = line[6].replace('users:(("', '').replace(/"/g, '').split(','); if (proc.length > 2) { process = proc[0].split(' ')[0].split(':')[0]; pid = parseInt(proc[1], 10); } } if (connstate) { result.push({ protocol: line[0], localAddress: localip, localPort: localport, peerAddress: peerip, peerPort: peerport, state: connstate, pid, process }); } } }); } if (callback) { callback(result); } resolve(result); }); } }); } if (_darwin) { let cmd = 'netstat -natvln | head -n2; netstat -natvln | grep "tcp4\\|tcp6\\|udp4\\|udp6"'; const states = 'ESTABLISHED|SYN_SENT|SYN_RECV|FIN_WAIT1|FIN_WAIT_1|FIN_WAIT2|FIN_WAIT_2|TIME_WAIT|CLOSE|CLOSE_WAIT|LAST_ACK|LISTEN|CLOSING|UNKNOWN'.split('|'); exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) { if (!error) { exec('ps -axo pid,command', { maxBuffer: 1024 * 20000 }, function (err2, stdout2) { let processes = stdout2.toString().split('\n'); processes = processes.map((line => { return line.trim().replace(/ +/g, ' '); })); let lines = stdout.toString().split('\n'); lines.shift(); let pidPos = 8; if (lines.length > 1 && lines[0].indexOf('pid') > 0) { const header = (lines.shift() || '').replace(/ Address/g, '_Address').replace(/ +/g, ' ').split(' '); pidPos = header.indexOf('pid'); } lines.forEach(function (line) { line = line.replace(/ +/g, ' ').split(' '); if (line.length >= 8) { let localip = line[3]; let localport = ''; let localaddress = line[3].split('.'); if (localaddress.length > 1) { localport = localaddress[localaddress.length - 1]; localaddress.pop(); localip = localaddress.join('.'); } let peerip = line[4]; let peerport = ''; let peeraddress = line[4].split('.'); if (peeraddress.length > 1) { peerport = peeraddress[peeraddress.length - 1]; peeraddress.pop(); peerip = peeraddress.join('.'); } const hasState = states.indexOf(line[5]) >= 0; let connstate = hasState ? line[5] : 'UNKNOWN'; let pid = parseInt(line[pidPos + (hasState ? 0 : -1)], 10); if (connstate) { result.push({ protocol: line[0], localAddress: localip, localPort: localport, peerAddress: peerip, peerPort: peerport, state: connstate, pid: pid, process: getProcessName(processes, pid) }); } } }); if (callback) { callback(result); } resolve(result); }); } }); } if (_windows) { let cmd = 'netstat -nao'; try { exec(cmd, util.execOptsWin, function (error, stdout) { if (!error) { let lines = stdout.toString().split('\r\n'); lines.forEach(function (line) { line = line.trim().replace(/ +/g, ' ').split(' '); if (line.length >= 4) { let localip = line[1]; let localport = ''; let localaddress = line[1].split(':'); if (localaddress.length > 1) { localport = localaddress[localaddress.length - 1]; localaddress.pop(); localip = localaddress.join(':'); } localip = localip.replace(/\[/g, '').replace(/\]/g, ''); let peerip = line[2]; let peerport = ''; let peeraddress = line[2].split(':'); if (peeraddress.length > 1) { peerport = peeraddress[peeraddress.length - 1]; peeraddress.pop(); peerip = peeraddress.join(':'); } peerip = peerip.replace(/\[/g, '').replace(/\]/g, ''); let pid = util.toInt(line[4]); let connstate = line[3]; if (connstate === 'HERGESTELLT') { connstate = 'ESTABLISHED'; } if (connstate.startsWith('ABH')) { connstate = 'LISTEN'; } if (connstate === 'SCHLIESSEN_WARTEN') { connstate = 'CLOSE_WAIT'; } if (connstate === 'WARTEND') { connstate = 'TIME_WAIT'; } if (connstate === 'SYN_GESENDET') { connstate = 'SYN_SENT'; } if (connstate === 'LISTENING') { connstate = 'LISTEN'; } if (connstate === 'SYN_RECEIVED') { connstate = 'SYN_RECV'; } if (connstate === 'FIN_WAIT_1') { connstate = 'FIN_WAIT1'; } if (connstate === 'FIN_WAIT_2') { connstate = 'FIN_WAIT2'; } if (line[0].toLowerCase() !== 'udp' && connstate) { result.push({ protocol: line[0].toLowerCase(), localAddress: localip, localPort: localport, peerAddress: peerip, peerPort: peerport, state: connstate, pid, process: '' }); } else if (line[0].toLowerCase() === 'udp') { result.push({ protocol: line[0].toLowerCase(), localAddress: localip, localPort: localport, peerAddress: peerip, peerPort: peerport, state: '', pid: parseInt(line[3], 10), process: '' }); } } }); if (callback) { callback(result); } resolve(result); } }); } catch (e) { if (callback) { callback(result); } resolve(result); } } }); }); } exports.networkConnections = networkConnections; function networkGatewayDefault(callback) { return new Promise((resolve) => { process.nextTick(() => { let result = ''; if (_linux || _freebsd || _openbsd || _netbsd) { let cmd = 'ip route get 1'; try { exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) { if (!error) { let lines = stdout.toString().split('\n'); const line = lines && lines[0] ? lines[0] : ''; let parts = line.split(' via '); if (parts && parts[1]) { parts = parts[1].split(' '); result = parts[0]; } if (callback) { callback(result); } resolve(result); } else { if (callback) { callback(result); } resolve(result); } }); } catch (e) { if (callback) { callback(result); } resolve(result); } } if (_darwin) { let cmd = 'route -n get default'; try { exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) { if (!error) { const lines = stdout.toString().split('\n').map(line => line.trim()); result = util.getValue(lines, 'gateway'); } if (!result) { cmd = 'netstat -rn | awk \'/default/ {print $2}\''; exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) { const lines = stdout.toString().split('\n').map(line => line.trim()); result = lines.find(line => (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(line))); if (callback) { callback(result); } resolve(result); }); } else { if (callback) { callback(result); } resolve(result); } }); } catch (e) { if (callback) { callback(result); } resolve(result); } } if (_windows) { try { exec('netstat -r', util.execOptsWin, function (error, stdout) { const lines = stdout.toString().split(os.EOL); lines.forEach(line => { line = line.replace(/\s+/g, ' ').trim(); if (line.indexOf('0.0.0.0 0.0.0.0') > -1 && !(/[a-zA-Z]/.test(line))) { const parts = line.split(' '); if (parts.length >= 5 && (parts[parts.length - 3]).indexOf('.') > -1) { result = parts[parts.length - 3]; } } }); if (!result) { util.powerShell('Get-CimInstance -ClassName Win32_IP4RouteTable | Where-Object { $_.Destination -eq \'0.0.0.0\' -and $_.Mask -eq \'0.0.0.0\' }') .then((data) => { let lines = data.toString().split('\r\n'); if (lines.length > 1 && !result) { result = util.getValue(lines, 'NextHop'); if (callback) { callback(result); } resolve(result); // } else { // exec('ipconfig', util.execOptsWin, function (error, stdout) { // let lines = stdout.toString().split('\r\n'); // lines.forEach(function (line) { // line = line.trim().replace(/\. /g, ''); // line = line.trim().replace(/ +/g, ''); // const parts = line.split(':'); // if ((parts[0].toLowerCase().startsWith('standardgate') || parts[0].toLowerCase().indexOf('gateway') > -1 || parts[0].toLowerCase().indexOf('enlace') > -1) && parts[1]) { // result = parts[1]; // } // }); // if (callback) { callback(result); } // resolve(result); // }); } }); } else { if (callback) { callback(result); } resolve(result); } }); } catch (e) { if (callback) { callback(result); } resolve(result); } } }); }); } exports.networkGatewayDefault = networkGatewayDefault;