Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
248 kB · 8504 lines
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505/* * Copyright (c) 2004-2019 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */
/* * Modification History * * May 13, 2004 Allan Nathanson <ajn@apple.com> * - initial revision * which includes code originally authored by * Robert Ulrich <rulrich@apple.com> * Elizabeth Douglas <elizabeth@apple.com> * Quinn <eskimo1@apple.com> */
#include <TargetConditionals.h>#include <CoreFoundation/CoreFoundation.h>#include <CoreFoundation/CFRuntime.h>#include "SCNetworkConfigurationInternal.h"#include "SCPreferencesInternal.h"#include "SCHelper_client.h"#include "plugin_shared.h"
#if !TARGET_OS_IPHONE#include <EAP8021X/EAPClientProperties.h>#else // !TARGET_OS_IPHONE#ifndef kEAPClientPropUserName#define kEAPClientPropUserName CFSTR("UserName")#endif#ifndef kEAPClientPropUserPasswordKeychainItemID#define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")#endif#endif // !TARGET_OS_IPHONE
#include <IOKit/IOKitLib.h>#include <IOKit/IOCFBundle.h>#include <IOKit/IOBSD.h>#include <IOKit/network/IONetworkController.h>#include <IOKit/network/IONetworkInterface.h>#include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass#include <IOKit/serial/IOSerialKeys.h>#include <IOKit/storage/IOStorageDeviceCharacteristics.h>#if !TARGET_OS_SIMULATOR#include <IOKit/usb/IOUSBLib.h>#endif // !TARGET_OS_SIMULATOR
#include "dy_framework.h"
#ifndef kPCIThunderboltString#define kPCIThunderboltString "PCI-Thunderbolt"#endif
#if TARGET_OS_OSX#ifndef kUSBSupportsIPhoneOS#define kUSBSupportsIPhoneOS "SupportsIPhoneOS"#endif // !kUSBSupportsIPhoneOS#endif // TARGET_OS_OSX
#ifndef kIOUserEthernetInterfaceRoleKey#define kIOUserEthernetInterfaceRoleKey "InterfaceRole"#endif
#ifndef kIOUSBHostInterfaceClassName#define kIOUSBHostInterfaceClassName "IOUSBHostInterface"#endif
#include <string.h>#include <sysdir.h>#include <mach/mach.h>#include <net/if.h>#include <net/if_types.h>#include <net/if_dl.h>#include <net/route.h>#include <sys/ioctl.h>#include <sys/param.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/sysctl.h>#include <pthread.h>#include <ifaddrs.h>
/* CrashReporter "Application Specific Information" */#include <CrashReporterClient.h>
static CFStringRef copy_interface_string (CFBundleRef bundle, CFStringRef key, Boolean localized);static CFStringRef __SCNetworkInterfaceCopyDescription (CFTypeRef cf);static CFStringRef __SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf, CFDictionaryRef formatOptions);static void __SCNetworkInterfaceDeallocate (CFTypeRef cf);static Boolean __SCNetworkInterfaceEqual (CFTypeRef cf1, CFTypeRef cf2);static CFHashCode __SCNetworkInterfaceHash (CFTypeRef cf);static void __SCNetworkInterfaceCacheAdd (CFStringRef bsdName, CFArrayRef matchingInterfaces);static Boolean __SCNetworkInterfaceCacheIsOpen (void);static CFArrayRef __SCNetworkInterfaceCacheCopy (CFStringRef bsdName);
enum { kSortInternalModem = 0, kSortUSBModem, kSortModem, kSortBluetooth, kSortIrDA, kSortSerialPort, kSortWWAN, kSortEthernetPPP, kSortAirportPPP, kSortEthernet, kSortFireWire, kSortAirPort, kSortOtherWireless, kSortTethered, kSortWWANEthernet, kSortBluetoothPAN_GN, kSortBluetoothPAN_NAP, kSortBluetoothPAN_U, kSortThunderbolt, kSortCarPlay, kSortBond, kSortBridge, kSortVLAN, kSortUnknown};
static const char *sortOrderName[] = { "InternalModem", "USBModem", "Modem", "Bluetooth", "IrDA", "SerialPort", "WWAN", "EthernetPPP", "AirportPPP", "Ethernet", "FireWire", "AirPort", "OtherWireless", "Tethered", "WWANEthernet", "BluetoothPAN_GN", "BluetoothPAN_NAP", "BluetoothPAN_U", "Thunderbolt", "CarPlay", "Bond", "Bridge", "VLAN", "Unknown"};
const CFStringRef kSCNetworkInterfaceType6to4 = CFSTR("6to4");const CFStringRef kSCNetworkInterfaceTypeBluetooth = CFSTR("Bluetooth");const CFStringRef kSCNetworkInterfaceTypeBond = CFSTR("Bond");const CFStringRef kSCNetworkInterfaceTypeBridge = CFSTR("Bridge");const CFStringRef kSCNetworkInterfaceTypeEthernet = CFSTR("Ethernet");const CFStringRef kSCNetworkInterfaceTypeFireWire = CFSTR("FireWire");const CFStringRef kSCNetworkInterfaceTypeIEEE80211 = CFSTR("IEEE80211"); // IEEE 802.11, AirPortconst CFStringRef kSCNetworkInterfaceTypeIPSec = CFSTR("IPSec");const CFStringRef kSCNetworkInterfaceTypeIrDA = CFSTR("IrDA");const CFStringRef kSCNetworkInterfaceTypeL2TP = CFSTR("L2TP");const CFStringRef kSCNetworkInterfaceTypeLoopback = CFSTR("Loopback");const CFStringRef kSCNetworkInterfaceTypeModem = CFSTR("Modem");const CFStringRef kSCNetworkInterfaceTypePPP = CFSTR("PPP");const CFStringRef kSCNetworkInterfaceTypePPTP = CFSTR("PPTP");const CFStringRef kSCNetworkInterfaceTypeSerial = CFSTR("Serial");const CFStringRef kSCNetworkInterfaceTypeVLAN = CFSTR("VLAN");const CFStringRef kSCNetworkInterfaceTypeVPN = CFSTR("VPN");const CFStringRef kSCNetworkInterfaceTypeWWAN = CFSTR("WWAN");
const CFStringRef kSCNetworkInterfaceTypeIPv4 = CFSTR("IPv4");
static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4 = { .cfBase = INIT_CFRUNTIME_BASE(), // cfBase .sort_order = kSortUnknown, // sort_order};
const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4 = (SCNetworkInterfaceRef)&__kSCNetworkInterfaceIPv4;
static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback = { .cfBase = INIT_CFRUNTIME_BASE(), // cfBase .sort_order = kSortUnknown, // sort_order};
const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback = (SCNetworkInterfaceRef)&__kSCNetworkInterfaceLoopback;
static CFMutableSetRef vendor_interface_types = NULL;
// A thread-specific convenience cache of all interfaces matching a bsd name// Key: CFStringRef (BSD name)// Value: CFArrayRef (matching interfaces)static __thread CFMutableDictionaryRef S_interface_cache = NULL;
#pragma mark -#pragma mark SCNetworkInterface configuration details
#define doNone 0
#define do6to4 1<<0#define doL2TP 1<<1#define doPPP 1<<2#define doPPTP 1<<3#define doIPSec 1<<4#define doOverIP do6to4|doL2TP|doPPTP|doIPSec
#define doDNS 1<<1#define doIPv4 1<<2#define doIPv6 1<<3#define doProxies 1<<4#if !TARGET_OS_IPHONE#define doSMB 1<<5#else // !TARGET_OS_IPHONE#define doSMB 0#endif // !TARGET_OS_IPHONE
static const struct { const CFStringRef *interface_type; const CFStringRef *entity_hardware; Boolean per_interface_config; uint32_t supported_interfaces; const CFStringRef *ppp_subtype; uint32_t supported_protocols;} configurations[] = { // interface type entity_hardware if config? interface types PPP sub-type interface protocols // ===================================== ==================== ========== =============== ======================================= ========================================= { &kSCNetworkInterfaceType6to4 , &kSCEntNet6to4 , FALSE, doNone, NULL, doIPv6 }, { &kSCNetworkInterfaceTypeBluetooth , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, { &kSCNetworkInterfaceTypeBond , &kSCEntNetEthernet , TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeBridge , &kSCEntNetEthernet , TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeEthernet , &kSCEntNetEthernet , TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeFireWire , &kSCEntNetFireWire , TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeIEEE80211 , &kSCEntNetAirPort , TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeIPSec , &kSCEntNetIPSec , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeIrDA , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, { &kSCNetworkInterfaceTypeL2TP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypeL2TP, doNone }, { &kSCNetworkInterfaceTypeModem , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, { &kSCNetworkInterfaceTypePPP , &kSCEntNetPPP , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wdeprecated" { &kSCNetworkInterfaceTypePPTP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypePPTP, doNone },#pragma GCC diagnostic pop { &kSCNetworkInterfaceTypeSerial , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, { &kSCNetworkInterfaceTypeVLAN , &kSCEntNetEthernet , TRUE , doNone, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeVPN , &kSCEntNetVPN , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB }, { &kSCNetworkInterfaceTypeWWAN , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, // ===================================== =================== ========== =============== ======================================= ========================================= { &kSCNetworkInterfaceTypeLoopback , NULL , TRUE , doNone, NULL, doIPv4|doIPv6 }, // ===================================== =================== ========== =============== ======================================= ========================================= { &kSCNetworkInterfaceTypeIPv4 , NULL , FALSE, doOverIP, NULL, doNone }};
#define kSCNetworkInterfaceActive "Active"#define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"#define kSCNetworkInterfaceType "SCNetworkInterfaceType"#define kSCNetworkInterfaceBSDName kIOBSDNameKey#define kSCNetworkInterfaceIOBuiltin kIOBuiltin#define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix#define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType#define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit#define kSCNetworkInterfaceIOMACAddress kIOMACAddress#define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
#define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")static CFBundleRef bundle = NULL;
static CFTypeID __kSCNetworkInterfaceTypeID = _kCFRuntimeNotATypeID;
static const CFRuntimeClass __SCNetworkInterfaceClass = { 0, // version "SCNetworkInterface", // className NULL, // init NULL, // copy __SCNetworkInterfaceDeallocate, // dealloc __SCNetworkInterfaceEqual, // equal __SCNetworkInterfaceHash, // hash __SCNetworkInterfaceCopyFormattingDescription, // copyFormattingDesc __SCNetworkInterfaceCopyDescription // copyDebugDesc};
static pthread_once_t initialized = PTHREAD_ONCE_INIT;static pthread_once_t iokit_quiet = PTHREAD_ONCE_INIT;static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static mach_port_t masterPort = MACH_PORT_NULL;
static CFStringRef__SCNetworkInterfaceCopyDescription(CFTypeRef cf){ return __SCNetworkInterfaceCopyFormattingDescription(cf, NULL);}
static CFStringRef__SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions){ CFAllocatorRef allocator = CFGetAllocator(cf); CFMutableStringRef result; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)cf;
result = CFStringCreateMutable(allocator, 0); CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkInterface %p [%p]> {"), cf, allocator); CFStringAppendFormat(result, NULL, CFSTR("type = %@"), interfacePrivate->interface_type); CFStringAppendFormat(result, NULL, CFSTR(", entity_device = %@"), interfacePrivate->entity_device); if (interfacePrivate->entity_device_unique != NULL) { CFStringAppendFormat(result, NULL, CFSTR("+%@"), interfacePrivate->entity_device_unique); } CFStringAppendFormat(result, NULL, CFSTR(", entity_type = %@"), interfacePrivate->entity_type); if (interfacePrivate->entity_subtype != NULL) { CFStringAppendFormat(result, NULL, CFSTR(" / %@"), interfacePrivate->entity_subtype); } if (interfacePrivate->name != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", name = %@"), interfacePrivate->name); } if (interfacePrivate->localized_name != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", name(l) = %@"), interfacePrivate->localized_name); } else { if (interfacePrivate->localized_key != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", name(k) = \"%@\""), interfacePrivate->localized_key); if (interfacePrivate->localized_arg1 != NULL) { CFStringAppendFormat(result, NULL, CFSTR("+\"%@\""), interfacePrivate->localized_arg1); } if (interfacePrivate->localized_arg2 != NULL) { CFStringAppendFormat(result, NULL, CFSTR("+\"%@\""), interfacePrivate->localized_arg2); } } } if (interfacePrivate->address != NULL) { const uint8_t *data; CFIndex dataLen; CFIndex i;
CFStringAppendFormat(result, NULL, CFSTR(", address = "));
data = CFDataGetBytePtr(interfacePrivate->address); dataLen = CFDataGetLength(interfacePrivate->address); for (i = 0; i < dataLen; i++) { CFStringAppendFormat(result, NULL, CFSTR("%s%02x"), (i > 0) ? ":" : "", data[i]); } } CFStringAppendFormat(result, NULL, CFSTR(", builtin = %s"), interfacePrivate->builtin ? "TRUE" : "FALSE"); if (interfacePrivate->hidden) { CFStringAppendFormat(result, NULL, CFSTR(", hidden = TRUE")); }#if TARGET_OS_IPHONE if (interfacePrivate->trustRequired) { CFStringAppendFormat(result, NULL, CFSTR(", trust required = TRUE")); }#endif // TARGET_OS_IPHONE if (interfacePrivate->location != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", location = %@"), interfacePrivate->location); } if (interfacePrivate->path != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", path = %@"), interfacePrivate->path); } if (interfacePrivate->entryID != 0) { CFStringAppendFormat(result, NULL, CFSTR(", entryID = 0x%llx"), interfacePrivate->entryID); } if (interfacePrivate->type != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", type = %@"), interfacePrivate->type); } if (interfacePrivate->unit != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", unit = %@"), interfacePrivate->unit); } if (interfacePrivate->family != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", family = %@"), interfacePrivate->family); } if (interfacePrivate->subfamily != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", subfamily = %@"), interfacePrivate->subfamily); } if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) { int pid = 0; int vid = 0;
if (!isA_CFNumber(interfacePrivate->usb.pid) || !CFNumberGetValue(interfacePrivate->usb.pid, kCFNumberIntType, &pid)) { pid = 0; } if (!isA_CFNumber(interfacePrivate->usb.vid) || !CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid)) { vid = 0; }
if (interfacePrivate->usb.name != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", USB name = %@"), interfacePrivate->usb.name); }
CFStringAppendFormat(result, NULL, CFSTR(", USB vid/pid = 0x%0x/0x%0x"), vid, pid); } if (interfacePrivate->configurationAction != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", action = %@"), interfacePrivate->configurationAction); } if (interfacePrivate->overrides != NULL) { CFStringRef str;
str = _SCCopyDescription(interfacePrivate->overrides, formatOptions); CFStringAppendFormat(result, formatOptions, CFSTR(", overrides = %@"), str); CFRelease(str); } CFStringAppendFormat(result, NULL, CFSTR(", order = %d (%s)"), interfacePrivate->sort_order, interfacePrivate->sort_order <= kSortUnknown ? sortOrderName[interfacePrivate->sort_order] : "?"); if (interfacePrivate->prefs != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", prefs = %p"), interfacePrivate->prefs); } if (interfacePrivate->serviceID != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", service = %@"), interfacePrivate->serviceID); } if (interfacePrivate->interface != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", interface = %@"), interfacePrivate->interface); } if (interfacePrivate->unsaved != NULL) { CFStringAppendFormat(result, formatOptions, CFSTR(", unsaved = %@"), interfacePrivate->unsaved); }
if (interfacePrivate->bond.interfaces != NULL) { CFIndex i; CFIndex n;
n = CFArrayGetCount(interfacePrivate->bond.interfaces); for (i = 0; i < n; i++) { SCNetworkInterfaceRef member;
member = CFArrayGetValueAtIndex(interfacePrivate->bond.interfaces, i); CFStringAppendFormat(result, NULL, CFSTR("%s%@"), (i == 0) ? ", interfaces = " : ",", SCNetworkInterfaceGetBSDName(member)); } } if (interfacePrivate->bond.mode != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", mode = %@"), interfacePrivate->bond.mode); } if (interfacePrivate->bond.options != NULL) { CFStringRef str;
str = _SCCopyDescription(interfacePrivate->bond.options, formatOptions); CFStringAppendFormat(result, formatOptions, CFSTR(", options = %@"), str); CFRelease(str); }
if (interfacePrivate->bridge.interfaces != NULL) { CFIndex i; CFIndex n;
n = CFArrayGetCount(interfacePrivate->bridge.interfaces); for (i = 0; i < n; i++) { SCNetworkInterfaceRef member;
member = CFArrayGetValueAtIndex(interfacePrivate->bridge.interfaces, i); CFStringAppendFormat(result, NULL, CFSTR("%s%@"), (i == 0) ? ", interfaces = " : ",", SCNetworkInterfaceGetBSDName(member)); } } if (interfacePrivate->bridge.options != NULL) { CFStringRef str;
str = _SCCopyDescription(interfacePrivate->bridge.options, formatOptions); CFStringAppendFormat(result, formatOptions, CFSTR(", options = %@"), str); CFRelease(str); }
if (interfacePrivate->vlan.interface != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", interface = %@"), SCNetworkInterfaceGetBSDName(interfacePrivate->vlan.interface)); } if (interfacePrivate->vlan.tag != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", tag = %@"), interfacePrivate->vlan.tag); } if (interfacePrivate->vlan.options != NULL) { CFStringRef str;
str = _SCCopyDescription(interfacePrivate->vlan.options, formatOptions); CFStringAppendFormat(result, formatOptions, CFSTR(", options = %@"), str); CFRelease(str); }
CFStringAppendFormat(result, NULL, CFSTR("}"));
return result;}
static void__SCNetworkInterfaceDeallocate(CFTypeRef cf){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)cf;
/* release resources */
if (interfacePrivate->name != NULL) CFRelease(interfacePrivate->name);
if (interfacePrivate->localized_name != NULL) CFRelease(interfacePrivate->localized_name);
if (interfacePrivate->localized_arg1 != NULL) CFRelease(interfacePrivate->localized_arg1);
if (interfacePrivate->localized_arg2 != NULL) CFRelease(interfacePrivate->localized_arg2);
if (interfacePrivate->interface != NULL) CFRelease(interfacePrivate->interface);
if (interfacePrivate->prefs != NULL) CFRelease(interfacePrivate->prefs);
if (interfacePrivate->store != NULL) CFRelease(interfacePrivate->store);
if (interfacePrivate->serviceID != NULL) CFRelease(interfacePrivate->serviceID);
if (interfacePrivate->unsaved != NULL) CFRelease(interfacePrivate->unsaved);
if (interfacePrivate->entity_device != NULL) CFRelease(interfacePrivate->entity_device);
if (interfacePrivate->entity_device_unique != NULL) CFRelease(interfacePrivate->entity_device_unique);
if (interfacePrivate->supported_interface_types != NULL) CFRelease(interfacePrivate->supported_interface_types);
if (interfacePrivate->supported_protocol_types != NULL) CFRelease(interfacePrivate->supported_protocol_types);
if (interfacePrivate->address != NULL) CFRelease(interfacePrivate->address);
if (interfacePrivate->addressString != NULL) CFRelease(interfacePrivate->addressString);
if (interfacePrivate->configurationAction != NULL) CFRelease(interfacePrivate->configurationAction);
if (interfacePrivate->location != NULL) CFRelease(interfacePrivate->location);
if (interfacePrivate->path != NULL) CFRelease(interfacePrivate->path);
if (interfacePrivate->overrides != NULL) CFRelease(interfacePrivate->overrides);
if (interfacePrivate->prefix != NULL) CFRelease(interfacePrivate->prefix);
if (interfacePrivate->type != NULL) CFRelease(interfacePrivate->type);
if (interfacePrivate->unit != NULL) CFRelease(interfacePrivate->unit);
if (interfacePrivate->family != NULL) CFRelease(interfacePrivate->family);
if (interfacePrivate->subfamily != NULL) CFRelease(interfacePrivate->subfamily);
if (interfacePrivate->usb.name != NULL) CFRelease(interfacePrivate->usb.name);
if (interfacePrivate->usb.pid != NULL) CFRelease(interfacePrivate->usb.pid);
if (interfacePrivate->usb.vid != NULL) CFRelease(interfacePrivate->usb.vid);
if (interfacePrivate->bond.interfaces != NULL) CFRelease(interfacePrivate->bond.interfaces);
if (interfacePrivate->bond.mode != NULL) CFRelease(interfacePrivate->bond.mode);
if (interfacePrivate->bond.options != NULL) CFRelease(interfacePrivate->bond.options);
if (interfacePrivate->bridge.interfaces != NULL) CFRelease(interfacePrivate->bridge.interfaces);
if (interfacePrivate->bridge.options != NULL) CFRelease(interfacePrivate->bridge.options);
if (interfacePrivate->vlan.interface != NULL) CFRelease(interfacePrivate->vlan.interface);
if (interfacePrivate->vlan.tag != NULL) CFRelease(interfacePrivate->vlan.tag);
if (interfacePrivate->vlan.options != NULL) CFRelease(interfacePrivate->vlan.options);#if !TARGET_OS_SIMULATOR if (interfacePrivate->IPMonitorControl != NULL) CFRelease(interfacePrivate->IPMonitorControl);#endif // !TARGET_OS_SIMULATOR return;}
static Boolean__SCNetworkInterfaceEqual(CFTypeRef cf1, CFTypeRef cf2){ SCNetworkInterfacePrivateRef if1 = (SCNetworkInterfacePrivateRef)cf1; SCNetworkInterfacePrivateRef if2 = (SCNetworkInterfacePrivateRef)cf2;
if (if1 == if2) return TRUE;
if (!CFEqual(if1->interface_type, if2->interface_type)) { return FALSE; // if not the same interface type }
if (!_SC_CFEqual(if1->entity_device, if2->entity_device)) { return FALSE; // if not the same device }
if ((if1->entity_device_unique != NULL) && (if2->entity_device_unique != NULL)) { if (!_SC_CFEqual(if1->entity_device_unique, if2->entity_device_unique)) { return FALSE; // if not the same device unique identifier } } else if ((if1->entity_device_unique != NULL) || (if2->entity_device_unique != NULL)) { CFStringRef name1; CFStringRef name2;
name1 = __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef)if1); name2 = __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef)if2); if ((name1 != NULL) && (name2 != NULL) && !_SC_CFEqual(name1, name2)) { return FALSE; // if same device but not the same display name } }
if (CFEqual(if1->interface_type, kSCNetworkInterfaceTypeBond)) { if (!_SC_CFEqual(if1->bond.interfaces, if2->bond.interfaces)) { return FALSE; // if not the same interfaces } if (!_SC_CFEqual(if1->bond.mode, if2->bond.mode)) { return FALSE; // if not the same mode } }
if (CFEqual(if1->interface_type, kSCNetworkInterfaceTypeBridge)) { if (!_SC_CFEqual(if1->bridge.interfaces, if2->bridge.interfaces)) { return FALSE; // if not the same interfaces } }
if (CFEqual(if1->interface_type, kSCNetworkInterfaceTypeVLAN)) { if (!_SC_CFEqual(if1->vlan.interface, if2->vlan.interface)) { return FALSE; // if not the same physical interface } if (!_SC_CFEqual(if1->vlan.tag, if2->vlan.tag)) { return FALSE; // if not the same tag } }
if (!_SC_CFEqual(if1->interface, if2->interface)) { return FALSE; // if not the same layering }
return TRUE;}
static CFHashCode__SCNetworkInterfaceHash(CFTypeRef cf){ CFHashCode hash = 0; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)cf;
if (interfacePrivate->entity_device != NULL) { if (interfacePrivate->entity_device_unique == NULL) { hash = CFHash(interfacePrivate->entity_device); } else { CFStringRef str;
str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@+%@"), interfacePrivate->entity_device, interfacePrivate->entity_device_unique); hash = CFHash(str); CFRelease(str); } }
return hash;}
static void__SCNetworkInterfaceInitialize(void){ kern_return_t kr;
// register w/CF __kSCNetworkInterfaceTypeID = _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass);
// initialize __kSCNetworkInterfaceIPv4 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4, __kSCNetworkInterfaceTypeID); __kSCNetworkInterfaceIPv4.interface_type = kSCNetworkInterfaceTypeIPv4; __kSCNetworkInterfaceIPv4.localized_key = CFSTR("ipv4");
// initialize __kSCNetworkInterfaceLoopback _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback, __kSCNetworkInterfaceTypeID); __kSCNetworkInterfaceLoopback.interface_type = kSCNetworkInterfaceTypeLoopback; __kSCNetworkInterfaceLoopback.localized_key = CFSTR("loopback"); __kSCNetworkInterfaceLoopback.entity_device = CFRetain(CFSTR("lo0")); __kSCNetworkInterfaceLoopback.entity_type = kSCValNetInterfaceTypeLoopback;
// get CFBundleRef for SystemConfiguration.framework bundle = _SC_CFBundleGet();
// get mach port used to communication with IOKit kr = IOMasterPort(MACH_PORT_NULL, &masterPort); if (kr != kIOReturnSuccess) { SC_log(LOG_NOTICE, "could not get IOMasterPort, kr = 0x%x", kr); }
return;}
__private_extern__SCNetworkInterfacePrivateRef__SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator, SCNetworkInterfaceRef interface, SCPreferencesRef prefs, CFStringRef serviceID){ SCNetworkInterfacePrivateRef interfacePrivate; uint32_t size;
/* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
/* allocate target */ size = sizeof(SCNetworkInterfacePrivate) - sizeof(CFRuntimeBase); interfacePrivate = (SCNetworkInterfacePrivateRef)_CFRuntimeCreateInstance(allocator, __kSCNetworkInterfaceTypeID, size, NULL); if (interfacePrivate == NULL) { return NULL; }
/* initialize non-zero/NULL members */ interfacePrivate->interface = (interface != NULL) ? CFRetain(interface) : NULL; interfacePrivate->prefs = (prefs != NULL) ? CFRetain(prefs) : NULL; interfacePrivate->serviceID = (serviceID != NULL) ? CFRetain(serviceID) : NULL; interfacePrivate->sort_order = kSortUnknown;
return interfacePrivate;}
__private_extern__Boolean__SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if){ char * buf = NULL; size_t buf_len = 0; struct if_msghdr * ifm; char * if_name = NULL; unsigned int if_index; int mib[6]; Boolean vlanOK = FALSE;
// get the interface index if_name = _SC_cfstring_to_cstring(bsd_if, NULL, 0, kCFStringEncodingASCII); if (if_name == NULL) { return FALSE; // if conversion error } if_index = if_nametoindex(if_name); if (if_index == 0) { goto done; // if unknown interface }
// get information for the specified interface mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; mib[5] = if_index; /* ask for exactly one interface */
if (sysctl(mib, 6, NULL, &buf_len, NULL, 0) == -1) { SC_log(LOG_NOTICE, "sysctl() size failed: %s", strerror(errno)); goto done; } buf = CFAllocatorAllocate(NULL, buf_len, 0); if (sysctl(mib, 6, buf, &buf_len, NULL, 0) == -1) { SC_log(LOG_NOTICE, "sysctl() failed: %s", strerror(errno)); goto done; }
// check the link type and hwassist flags // ALIGN: buf is aligned ifm = (struct if_msghdr *)(void *)buf; switch (ifm->ifm_type) { case RTM_IFINFO : {#if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU) struct if_data *if_data = &ifm->ifm_data;
if (if_data->ifi_hwassist & (IF_HWASSIST_VLAN_TAGGING | IF_HWASSIST_VLAN_MTU)) { vlanOK = TRUE; }#endif break; } }
done :
if (if_name != NULL) CFAllocatorDeallocate(NULL, if_name); if (buf != NULL) CFAllocatorDeallocate(NULL, buf);
return vlanOK;}
static CFDataRef__SCCopyMacAddress(CFStringRef ifname){ struct ifaddrs *ifap; char ifname_c[IFNAMSIZ]; struct ifaddrs *ifp; CFDataRef macAddress = NULL;
if(_SC_cfstring_to_cstring(ifname, ifname_c, sizeof(ifname_c), kCFStringEncodingUTF8) == NULL) { return NULL; }
if (getifaddrs(&ifap) == -1) { _SCErrorSet(errno); SC_log(LOG_NOTICE, "getifaddrs() failed: %s", strerror(errno)); return NULL; }
for (ifp = ifap; ifp != NULL; ifp = ifp->ifa_next) { struct sockaddr_dl *sdl;
if(strcmp(ifname_c, ifp->ifa_name) != 0) { continue; }
/* ALIGN: cast ok, this should be aligned (getifaddrs). */ sdl = (struct sockaddr_dl *)(void *)ifp->ifa_addr; if (sdl->sdl_family != AF_LINK) { continue; }
macAddress = CFDataCreate(NULL, (UInt8 *)LLADDR(sdl), sdl->sdl_alen); break; } freeifaddrs(ifap); return macAddress;}
__private_extern__SCNetworkInterfacePrivateRef_SCBondInterfaceCreatePrivate(CFAllocatorRef allocator, CFStringRef bond_if){ SCNetworkInterfacePrivateRef interfacePrivate;
interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL); if (interfacePrivate == NULL) { return NULL; }
interfacePrivate->interface_type = kSCNetworkInterfaceTypeBond; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->entity_device = CFStringCreateCopy(allocator, bond_if); interfacePrivate->address = __SCCopyMacAddress(interfacePrivate->entity_device); interfacePrivate->builtin = TRUE; interfacePrivate->supportsVLAN = __SCNetworkInterfaceSupportsVLAN(bond_if); interfacePrivate->sort_order = kSortBond;
interfacePrivate->localized_key = CFSTR("bond"); interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->entity_device);
interfacePrivate->bond.interfaces = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);// interfacePrivate->bond.mode = NULL;// interfacePrivate->bond.options = NULL;
return interfacePrivate;}
__private_extern__SCNetworkInterfacePrivateRef_SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator, CFStringRef bridge_if){ SCNetworkInterfacePrivateRef interfacePrivate;
interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL); if (interfacePrivate == NULL) { return NULL; }
interfacePrivate->interface_type = kSCNetworkInterfaceTypeBridge; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->entity_device = CFStringCreateCopy(allocator, bridge_if); interfacePrivate->address = __SCCopyMacAddress(interfacePrivate->entity_device); interfacePrivate->builtin = TRUE; interfacePrivate->supportsVLAN = __SCNetworkInterfaceSupportsVLAN(bridge_if); interfacePrivate->sort_order = kSortBridge;
interfacePrivate->localized_key = CFSTR("bridge"); interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->entity_device);
interfacePrivate->bridge.interfaces = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);// interfacePrivate->bridge.options = NULL;
return interfacePrivate;}
__private_extern__SCNetworkInterfacePrivateRef_SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator, CFStringRef vlan_if){ SCNetworkInterfacePrivateRef interfacePrivate;
interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL); if (interfacePrivate == NULL) { return NULL; }
interfacePrivate->interface_type = kSCNetworkInterfaceTypeVLAN; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->entity_device = CFStringCreateCopy(allocator, vlan_if); interfacePrivate->address = __SCCopyMacAddress(interfacePrivate->entity_device); interfacePrivate->builtin = TRUE; interfacePrivate->sort_order = kSortVLAN;
interfacePrivate->localized_key = CFSTR("vlan"); interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->entity_device);
// interfacePrivate->vlan.interface = NULL;// interfacePrivate->vlan.tag = NULL;// interfacePrivate->vlan.options = NULL;
return interfacePrivate;}
#pragma mark -#pragma mark Interface ordering
static CF_RETURNS_RETAINED CFArrayRefsplit_path(CFStringRef path){ CFArrayRef components; CFMutableStringRef nPath;
// turn '@'s into '/'s nPath = CFStringCreateMutableCopy(NULL, 0, path); (void) CFStringFindAndReplace(nPath, CFSTR("@"), CFSTR("/"), CFRangeMake(0, CFStringGetLength(nPath)), 0);
// split path into components to be compared components = CFStringCreateArrayBySeparatingStrings(NULL, nPath, CFSTR("/")); CFRelease(nPath);
return components;}
CFComparisonResult_SCNetworkInterfaceCompare(const void *val1, const void *val2, void *context){#pragma unused(context) SCNetworkInterfacePrivateRef dev1 = (SCNetworkInterfacePrivateRef)val1; SCNetworkInterfacePrivateRef dev2 = (SCNetworkInterfacePrivateRef)val2; CFComparisonResult res = kCFCompareEqualTo;
/* sort by interface type */ if (dev1->sort_order != dev2->sort_order) { if (dev1->sort_order < dev2->sort_order) { res = kCFCompareLessThan; } else { res = kCFCompareGreaterThan; } return (res); }
/* built-in interfaces sort first */ if (dev1->builtin != dev2->builtin) { if (dev1->builtin) { res = kCFCompareLessThan; } else { res = kCFCompareGreaterThan; } return (res); }
/* ... and then, sort built-in interfaces by "location" */ if (dev1->builtin) { if (dev1->location != dev2->location) { if (isA_CFString(dev1->location)) { if (isA_CFString(dev2->location)) { res = CFStringCompare(dev1->location, dev2->location, 0); } else { res = kCFCompareLessThan; } } else { res = kCFCompareGreaterThan; }
if (res != kCFCompareEqualTo) { return (res); } } }
/* ... and, then sort by IOPathMatch */ if ((dev1->path != NULL) && (dev2->path != NULL)) { CFArrayRef elements1; CFArrayRef elements2; CFIndex i; CFIndex n; CFIndex n1; CFIndex n2;
elements1 = split_path(dev1->path); n1 = CFArrayGetCount(elements1);
elements2 = split_path(dev2->path); n2 = CFArrayGetCount(elements2);
n = (n1 <= n2) ? n1 : n2; for (i = 0; i < n; i++) { CFStringRef e1; CFStringRef e2; char *end; quad_t q1; quad_t q2; char *str; Boolean isNum;
e1 = CFArrayGetValueAtIndex(elements1, i); e2 = CFArrayGetValueAtIndex(elements2, i);
str = _SC_cfstring_to_cstring(e1, NULL, 0, kCFStringEncodingUTF8); errno = 0; q1 = strtoq(str, &end, 16); isNum = ((*str != '\0') && (*end == '\0') && (errno == 0)); CFAllocatorDeallocate(NULL, str);
if (isNum) { // if e1 is a valid numeric string str = _SC_cfstring_to_cstring(e2, NULL, 0, kCFStringEncodingUTF8); errno = 0; q2 = strtoq(str, &end, 16); isNum = ((*str != '\0') && (*end == '\0') && (errno == 0)); CFAllocatorDeallocate(NULL, str);
if (isNum) { // if e2 is also a valid numeric string
if (q1 == q2) { res = kCFCompareEqualTo; continue; } else if (q1 < q2) { res = kCFCompareLessThan; } else { res = kCFCompareGreaterThan; } break; } }
res = CFStringCompare(e1, e2, 0); if (res != kCFCompareEqualTo) { break; } }
if (res == kCFCompareEqualTo) { if (n1 < n2) { res = kCFCompareLessThan; } else if (n1 < n2) { res = kCFCompareGreaterThan; } }
CFRelease(elements1); CFRelease(elements2);
if (res != kCFCompareEqualTo) { return (res); } }
/* ... and, then sort by BSD interface name */ if ((dev1->entity_device != NULL) && (dev2->entity_device != NULL)) { res = CFStringCompare(dev1->entity_device, dev2->entity_device, 0); if (res != kCFCompareEqualTo) { return (res); } }
/* ... and lastly, sort by BSD interface unique identifier */ if ((dev1->entity_device_unique != NULL) && (dev2->entity_device_unique != NULL)) { res = CFStringCompare(dev1->entity_device_unique, dev2->entity_device_unique, 0);// if (res != kCFCompareEqualTo) {// return (res);// } }
return res;}
static voidsort_interfaces(CFMutableArrayRef all_interfaces){ CFIndex n;
n = CFArrayGetCount(all_interfaces); if (n < 2) { return; }
CFArraySortValues(all_interfaces, CFRangeMake(0, n), _SCNetworkInterfaceCompare, NULL); return;}
__private_extern__int__SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->sort_order;}
#pragma mark -#pragma mark Interface details
static CFStringRefIOCopyCFStringValue(CFTypeRef ioVal){ if (isA_CFString(ioVal)) { return CFStringCreateCopy(NULL, ioVal); }
if (isA_CFData(ioVal)) { return CFStringCreateWithCString(NULL, (const char *)CFDataGetBytePtr(ioVal), kCFStringEncodingUTF8); }
return NULL;}
static CFStringRefIODictionaryCopyBSDName(CFDictionaryRef io_dict){ CFStringRef if_bsdName; CFStringRef if_prefix; CFNumberRef if_unit;
if_bsdName = CFDictionaryGetValue(io_dict, CFSTR(kIOBSDNameKey)); if (if_bsdName != NULL) { return IOCopyCFStringValue(if_bsdName); }
// no BSD name, get interface prefix and unit if_prefix = CFDictionaryGetValue(io_dict, CFSTR(kIOInterfaceNamePrefix)); if_unit = CFDictionaryGetValue(io_dict, CFSTR(kIOInterfaceUnit)); if (isA_CFString(if_prefix) && isA_CFNumber(if_unit)) { // if both prefix and unit available, construct BSD name if_bsdName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), if_prefix, if_unit); }
return if_bsdName;};
static CFStringRefIODictionaryCopyCFStringValue(CFDictionaryRef io_dict, CFStringRef io_key){ CFTypeRef ioVal;
ioVal = CFDictionaryGetValue(io_dict, io_key); return IOCopyCFStringValue(ioVal);}
static BooleanIOStringValueHasPrefix(CFTypeRef ioVal, CFStringRef prefix){ Boolean match = FALSE; CFIndex prefixLen = CFStringGetLength(prefix); CFStringRef str = NULL;
if (!isA_CFString(ioVal)) { if (isA_CFData(ioVal)) { str = CFStringCreateWithCStringNoCopy(NULL, (const char *)CFDataGetBytePtr(ioVal), kCFStringEncodingUTF8, kCFAllocatorNull); ioVal = str; } else { return FALSE; } }
if ((ioVal != NULL) && (CFStringGetLength(ioVal) >= prefixLen) && (CFStringCompareWithOptions(ioVal, prefix, CFRangeMake(0, prefixLen), kCFCompareCaseInsensitive) == kCFCompareEqualTo)) { match = TRUE; }
if (str != NULL) CFRelease(str); return match;}
static const struct { const CFStringRef name; const CFStringRef slot;} slot_mappings[] = { // Beige G3 { CFSTR("A1") , CFSTR("1") }, { CFSTR("B1") , CFSTR("2") }, { CFSTR("C1") , CFSTR("3") },
// Blue&White G3, Yikes G4 { CFSTR("J12"), CFSTR("1") }, { CFSTR("J11"), CFSTR("2") }, { CFSTR("J10"), CFSTR("3") }, { CFSTR("J9"), CFSTR("4") },
// AGP G4 { CFSTR("A") , CFSTR("1") }, { CFSTR("B") , CFSTR("2") }, { CFSTR("C") , CFSTR("3") }, { CFSTR("D") , CFSTR("4") },
// Digital Audio G4 (and later models) { CFSTR("1") , CFSTR("1") }, { CFSTR("2") , CFSTR("2") }, { CFSTR("3") , CFSTR("3") }, { CFSTR("4") , CFSTR("4") }, { CFSTR("5") , CFSTR("5") }};
static const CFStringRef slot_prefixes[] = { CFSTR("thunderbolt slot "), CFSTR("pci slot "), CFSTR("slot-"),};
static CF_RETURNS_RETAINED CFStringRefpci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name){ kern_return_t kr; io_registry_entry_t parent; CFMutableStringRef slot; CFTypeRef slot_name;
slot = NULL; if (pci_slot_name != NULL) *pci_slot_name = NULL;
slot_name = IORegistryEntryCreateCFProperty(interface, CFSTR("AAPL,slot-name"), NULL, 0); if (slot_name != NULL) { slot = CFStringCreateMutable(NULL, 0); if (isA_CFString(slot_name)) { if (pci_slot_name != NULL) *pci_slot_name = CFStringCreateCopy(NULL, slot_name); CFStringAppend(slot, slot_name); } else if (isA_CFData(slot_name)) { if (pci_slot_name != NULL) *pci_slot_name = CFDataCreateCopy(NULL, slot_name); CFStringAppendCString(slot, (const char *)CFDataGetBytePtr(slot_name), kCFStringEncodingUTF8); }
for (size_t i = 0; i < sizeof(slot_prefixes)/sizeof(slot_prefixes[0]); i++) { CFIndex len;
len = CFStringGetLength(slot_prefixes[i]); if (CFStringGetLength(slot) > len) { (void) CFStringFindAndReplace(slot, slot_prefixes[i], CFSTR(""), CFRangeMake(0, len), kCFCompareCaseInsensitive|kCFCompareAnchored); } }
for (size_t i = 0; i < sizeof(slot_mappings)/sizeof(slot_mappings[0]); i++) { if (CFStringCompare(slot, slot_mappings[i].name, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { CFRelease(slot); slot = (CFMutableStringRef)CFRetain(slot_mappings[i].slot); break; } }
CFRelease(slot_name); }
kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &parent); switch (kr) { case kIOReturnSuccess : { CFTypeRef parent_pci_slot_name = NULL; CFStringRef parent_slot;
parent_slot = pci_slot(parent, &parent_pci_slot_name); if (parent_slot != NULL) { if (slot != NULL) CFRelease(slot); slot = (CFMutableStringRef)parent_slot;
if (pci_slot_name != NULL) { if (*pci_slot_name != NULL) CFRelease(*pci_slot_name); *pci_slot_name = parent_pci_slot_name; } else { if (parent_pci_slot_name != NULL) CFRelease(parent_pci_slot_name); } }
IOObjectRelease(parent); break; } case kIOReturnNoDevice : // if we have hit the root node break; default : SC_log(LOG_INFO, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr); break; }
return slot;}
static CFComparisonResultcompare_bsdNames(const void *val1, const void *val2, void *context){#pragma unused(context) CFStringRef bsd1 = (CFStringRef)val1; CFStringRef bsd2 = (CFStringRef)val2;
return CFStringCompare(bsd1, bsd2, 0);}
static CF_RETURNS_RETAINED CFStringRefpci_port(CFTypeRef slot_name, int ift, CFStringRef bsdName){ CFIndex n; CFStringRef port_name = NULL; CFMutableArrayRef port_names;
kern_return_t kr; CFStringRef match_keys[2]; CFTypeRef match_vals[2]; CFDictionaryRef match_dict; CFDictionaryRef matching; io_registry_entry_t slot; io_iterator_t slot_iterator = MACH_PORT_NULL;
match_keys[0] = CFSTR("AAPL,slot-name"); match_vals[0] = slot_name;
match_dict = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
match_keys[0] = CFSTR(kIOProviderClassKey); match_vals[0] = CFSTR("IOPCIDevice");
match_keys[1] = CFSTR(kIOPropertyMatchKey); match_vals[1] = match_dict;
// note: the "matching" dictionary will be consumed by the following matching = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(match_dict);
kr = IOServiceGetMatchingServices(masterPort, matching, &slot_iterator); if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr); return MACH_PORT_NULL; }
port_names = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
while ((slot = IOIteratorNext(slot_iterator)) != MACH_PORT_NULL) { io_registry_entry_t child; io_iterator_t child_iterator = MACH_PORT_NULL;
kr = IORegistryEntryCreateIterator(slot, kIOServicePlane, kIORegistryIterateRecursively, &child_iterator); if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr); CFRelease(port_names); return MACH_PORT_NULL; }
while ((child = IOIteratorNext(child_iterator)) != MACH_PORT_NULL) { if (IOObjectConformsTo(child, kIONetworkInterfaceClass)) { CFMutableDictionaryRef interface_dict = NULL;
(void) IORegistryEntryCreateCFProperties(child, &interface_dict, NULL, kNilOptions); if (interface_dict != NULL) { CFNumberRef child_if_type; int child_ift = ift;
child_if_type = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceType)); if (child_if_type != NULL) { if (!isA_CFNumber(child_if_type) || !CFNumberGetValue(child_if_type, kCFNumberIntType, &child_ift)) { // assume that it's a match child_ift = ift; } }
if (ift == child_ift) { CFStringRef if_bsdName;
if_bsdName = IODictionaryCopyBSDName(interface_dict); if (if_bsdName != NULL) { CFArrayAppendValue(port_names, if_bsdName); CFRelease(if_bsdName); } }
CFRelease(interface_dict); } } IOObjectRelease(child); } IOObjectRelease(child_iterator); IOObjectRelease(slot); } IOObjectRelease(slot_iterator);
n = CFArrayGetCount(port_names); if (n > 1) { CFArraySortValues(port_names, CFRangeMake(0, n), compare_bsdNames, NULL); n = CFArrayGetFirstIndexOfValue(port_names, CFRangeMake(0, n), bsdName); if (n != kCFNotFound) { port_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), n + 1); } }
CFRelease(port_names); return port_name;}
static Booleanpci_slot_info(io_registry_entry_t interface, int ift, CFStringRef *slot_name, CFStringRef *port_name){ CFStringRef bsd_name = NULL; CFMutableDictionaryRef interface_dict = NULL; Boolean ok = FALSE; CFTypeRef pci_slot_name;
*slot_name = NULL; *port_name = NULL;
(void) IORegistryEntryCreateCFProperties(interface, &interface_dict, NULL, kNilOptions); if (interface_dict != NULL) { bsd_name = IODictionaryCopyBSDName(interface_dict); CFRelease(interface_dict); }
if (bsd_name == NULL) { return FALSE; }
*slot_name = pci_slot(interface, &pci_slot_name); if (*slot_name != NULL) { if (pci_slot_name != NULL) { *port_name = pci_port(pci_slot_name, ift, bsd_name); CFRelease(pci_slot_name); } ok = TRUE; }
CFRelease(bsd_name); return ok;}
static BooleanisBuiltin(io_registry_entry_t interface){ CFStringRef slot;
slot = pci_slot(interface, NULL); if (slot != NULL) { // interfaces which have a "slot" are not built-in CFRelease(slot); return FALSE; }
return TRUE;}
static BooleanisBluetoothBuiltin(Boolean *haveController){ Boolean builtin = FALSE; io_object_t hciController; io_iterator_t iter = MACH_PORT_NULL; kern_return_t kr;
kr = IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOBluetoothHCIController"), &iter); if ((kr != kIOReturnSuccess) || (iter == MACH_PORT_NULL)) { if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr); } *haveController = FALSE; return FALSE; } *haveController = TRUE;
hciController = IOIteratorNext(iter); IOObjectRelease(iter); if(hciController != MACH_PORT_NULL) {#if !TARGET_OS_SIMULATOR CFNumberRef idVendor;
idVendor = IORegistryEntryCreateCFProperty(hciController, CFSTR(kUSBVendorID), NULL, 0); if (idVendor != NULL) { int idVendorVal;
if (isA_CFNumber(idVendor) && CFNumberGetValue(idVendor, kCFNumberIntType, &idVendorVal) && (idVendorVal == kIOUSBVendorIDAppleComputer)) { builtin = TRUE; }
CFRelease(idVendor); }#endif // !TARGET_OS_SIMULATOR
IOObjectRelease(hciController); }
return builtin;}
static BooleanisThunderbolt(io_registry_entry_t interface){ CFTypeRef val;
val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kPCIThunderboltString), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { CFRelease(val); return TRUE; }
return FALSE;}
static voidprocessUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t interface, CFDictionaryRef interface_dict, io_registry_entry_t controller, CFDictionaryRef controller_dict, io_registry_entry_t bus, CFDictionaryRef bus_dict){#if TARGET_OS_SIMULATOR#pragma unused(interfacePrivate)#pragma unused(interface)#endif // TARGET_OS_SIMULATOR#pragma unused(interface_dict)#pragma unused(controller)#pragma unused(controller_dict)#pragma unused(bus)#pragma unused(bus_dict)#if !TARGET_OS_SIMULATOR // capture USB info if (interfacePrivate->usb.name == NULL) { interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kUSBProductString), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); } if (interfacePrivate->usb.vid == NULL) { interfacePrivate->usb.vid = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kUSBVendorID), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); } if (interfacePrivate->usb.pid == NULL) { interfacePrivate->usb.pid = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kUSBProductID), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); }#endif // !TARGET_OS_SIMULATOR
return;}
static Booleanupdate_interface_name(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t interface, Boolean useUSBInfo){ Boolean updated = FALSE; CFTypeRef val;
// check if a "Product Name" has been provided val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kIOPropertyProductNameKey), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if ((val == NULL) && useUSBInfo && (interfacePrivate->usb.name != NULL)) { // else, use "USB Product Name" if available val = CFRetain(interfacePrivate->usb.name); } if (val != NULL) { CFStringRef productName;
productName = IOCopyCFStringValue(val); CFRelease(val);
if (productName != NULL) { if (CFStringGetLength(productName) > 0) { // if we have a [somewhat reasonable?] product name if (interfacePrivate->name != NULL) { CFRelease(interfacePrivate->name); } interfacePrivate->name = CFRetain(productName); if (interfacePrivate->localized_name != NULL) { CFRelease(interfacePrivate->localized_name); interfacePrivate->localized_name = NULL; } if (bundle != NULL) { interfacePrivate->localized_name = copy_interface_string(bundle, productName, TRUE); }
updated = TRUE; }
CFRelease(productName); } }
return updated;}
#pragma mark -#pragma mark Interface enumeration
typedef Boolean (*processInterface)(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t interface, CFDictionaryRef interface_dict, io_registry_entry_t controller, CFDictionaryRef controller_dict, io_registry_entry_t bus, CFDictionaryRef bus_dict);
static voidmerge_override(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t interface, CFStringRef override){ CFStringRef key; CFTypeRef val;
key = CFStringCreateWithFormat(NULL, NULL, CFSTR("Device%@Overrides"), override); val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, key, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); CFRelease(key); if (val != NULL) { if (isA_CFDictionary(val)) { if (interfacePrivate->overrides == NULL) { interfacePrivate->overrides = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(interfacePrivate->overrides, override, val); } CFRelease(val); }
return;}
static BooleanprocessNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t interface, CFDictionaryRef interface_dict, io_registry_entry_t controller, CFDictionaryRef controller_dict, io_registry_entry_t bus, CFDictionaryRef bus_dict){ CFDataRef data; int ift = -1; int iVal; CFNumberRef num; CFStringRef str; CFBooleanRef val;
// interface type num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceType)); if (isA_CFNumber(num) && CFNumberGetValue(num, kCFNumberIntType, &ift)) { interfacePrivate->type = CFRetain(num); } else { SC_log(LOG_INFO, "no interface type: %@", interface_dict); return FALSE; }
switch (ift) { case IFT_ETHER : // Type, Hardware
if (IOObjectConformsTo(controller, "IO80211Controller") || IOObjectConformsTo(controller, "AirPortPCI" ) || IOObjectConformsTo(controller, "AirPortDriver" )) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortAirPort; } else if (IOObjectConformsTo(controller, "AppleThunderboltIPPort")) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortThunderbolt; } else if (IOObjectConformsTo(controller, "IOBluetoothBNEPDriver")) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortBluetoothPAN_GN; } else if (IOObjectConformsTo(controller, "AppleUSBEthernetHost")) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortTethered; } else if (IOObjectConformsTo(controller, "AppleUSBCDCECMData")) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortWWANEthernet; }
if (interfacePrivate->interface_type == NULL) { val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kIOUserEthernetInterfaceRoleKey), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { if (isA_CFString(val)) { if (CFEqual(val, CFSTR(BT_PAN_NAME))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortBluetoothPAN_GN; } else if (CFEqual(val, CFSTR("Bluetooth PAN-NAP"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortBluetoothPAN_NAP; } else if (CFEqual(val, CFSTR("Bluetooth P2P"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortBluetoothPAN_U; } else if (CFEqual(val, CFSTR("CarPlay"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortCarPlay; } }
CFRelease(val); } }
#if TARGET_OS_OSX if (interfacePrivate->interface_type == NULL) { val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kUSBSupportsIPhoneOS), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { if (isA_CFBoolean(val) && CFBooleanGetValue(val)) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortTethered; }
CFRelease(val); } }#endif // TARGET_OS_OSX
if (interfacePrivate->interface_type == NULL) { str = IODictionaryCopyCFStringValue(bus_dict, CFSTR("name")); if (str != NULL) { if (CFEqual(str, CFSTR("radio"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; // ?? interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortOtherWireless; }
CFRelease(str); } }
if (interfacePrivate->interface_type == NULL) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; interfacePrivate->sort_order = kSortEthernet;
// BOND support only enabled for ethernet devices interfacePrivate->supportsBond = TRUE; }
// enable Bridge support interfacePrivate->supportsBridge = TRUE;
// built-in val = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOBuiltin))); if (val == NULL) { val = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOPrimaryInterface))); } if (val != NULL) { interfacePrivate->builtin = CFBooleanGetValue(val); } else { interfacePrivate->builtin = isBuiltin(interface); }
if (!interfacePrivate->builtin && CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) { // always treat AirPort interfaces as built-in interfacePrivate->builtin = TRUE; }
// location interfacePrivate->location = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOLocation)); if ((interfacePrivate->location != NULL) && (CFStringGetLength(interfacePrivate->location) == 0)) { CFRelease(interfacePrivate->location); interfacePrivate->location = NULL; }
// VLAN support num = CFDictionaryGetValue(controller_dict, CFSTR(kIOFeatures)); if (isA_CFNumber(num) && CFNumberGetValue(num, kCFNumberIntType, & iVal)) { if (iVal & (kIONetworkFeatureHardwareVlan | kIONetworkFeatureSoftwareVlan)) { interfacePrivate->supportsVLAN = TRUE; } }
// localized name if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) { interfacePrivate->localized_key = CFSTR("airport"); } else if (interfacePrivate->sort_order == kSortThunderbolt) { if ((interfacePrivate->location == NULL) || (CFStringGetLength(interfacePrivate->location) == 0)) { interfacePrivate->localized_key = CFSTR("thunderbolt"); } else { interfacePrivate->localized_key = CFSTR("multithunderbolt"); interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->location); } } else if (interfacePrivate->sort_order == kSortBluetoothPAN_GN) { interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn"); } else if (interfacePrivate->sort_order == kSortBluetoothPAN_NAP) { interfacePrivate->localized_key = CFSTR("bluetooth-pan-nap"); } else if (interfacePrivate->sort_order == kSortBluetoothPAN_U) { interfacePrivate->localized_key = CFSTR("bluetooth-pan-u"); } else if (interfacePrivate->sort_order == kSortOtherWireless) { interfacePrivate->localized_key = CFSTR("wireless"); interfacePrivate->localized_arg1 = CFRetain(CFSTR("")); // ?? } else if (interfacePrivate->builtin) { if ((interfacePrivate->location == NULL) || (CFStringGetLength(interfacePrivate->location) == 0)) { interfacePrivate->localized_key = CFSTR("ether"); } else { interfacePrivate->localized_key = CFSTR("multiether"); interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->location); } } else { CFStringRef provider;
// check provider class provider = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kIOProviderClassKey), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (provider != NULL) { if (CFEqual(provider, CFSTR("IOPCIDevice"))) { CFStringRef port_name; CFStringRef slot_name;
// set interface "name" if (!update_interface_name(interfacePrivate, interface, FALSE) && pci_slot_info(interface, ift, &slot_name, &port_name)) { if (isThunderbolt(interface)) { if (port_name == NULL) { interfacePrivate->localized_key = CFSTR("thunderbolt-ether"); interfacePrivate->localized_arg1 = slot_name; } else { interfacePrivate->localized_key = CFSTR("thunderbolt-multiether"); interfacePrivate->localized_arg1 = slot_name; interfacePrivate->localized_arg2 = port_name; }
} else { if (port_name == NULL) { interfacePrivate->localized_key = CFSTR("pci-ether"); interfacePrivate->localized_arg1 = slot_name; } else { interfacePrivate->localized_key = CFSTR("pci-multiether"); interfacePrivate->localized_arg1 = slot_name; interfacePrivate->localized_arg2 = port_name; } } } } else { io_registry_entry_t node = interface;
while (provider != NULL) {#if !TARGET_OS_SIMULATOR if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) || CFEqual(provider, CFSTR(kIOUSBInterfaceClassName)) || CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName))) { // get USB info (if available) processUSBInterface(interfacePrivate, interface, interface_dict, controller, controller_dict, bus, bus_dict);
// set interface "name" if (!update_interface_name(interfacePrivate, interface, TRUE)) { interfacePrivate->localized_key = CFSTR("usb-ether"); interfacePrivate->localized_arg1 = IODictionaryCopyBSDName(interface_dict); } break; }#endif // !TARGET_OS_SIMULATOR
if (node == interface) { node = controller; } else if (node == controller ) { node = bus; } else { break; }
CFRelease(provider); provider = IORegistryEntrySearchCFProperty(node, kIOServicePlane, CFSTR(kIOProviderClassKey), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); }
if (interfacePrivate->localized_key == NULL) { update_interface_name(interfacePrivate, interface, FALSE); } }
if (provider != NULL) CFRelease(provider); }
if (interfacePrivate->localized_key == NULL) { // if no provider, not a PCI device, or no slot information interfacePrivate->localized_key = CFSTR("generic-ether"); interfacePrivate->localized_arg1 = IODictionaryCopyBSDName(interface_dict); } }
break; case IFT_IEEE1394 : // Type interfacePrivate->interface_type = kSCNetworkInterfaceTypeFireWire;
// Entity interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire;
// built-in interfacePrivate->builtin = isBuiltin(interface);
// sort order interfacePrivate->sort_order = kSortFireWire;
// localized name if (interfacePrivate->builtin) { interfacePrivate->localized_key = CFSTR("firewire"); } else { CFStringRef port_name; CFStringRef slot_name;
// set interface "name" if (!update_interface_name(interfacePrivate, interface, FALSE) && pci_slot_info(interface, ift, &slot_name, &port_name)) { if (isThunderbolt(interface)) { if (port_name == NULL) { interfacePrivate->localized_key = CFSTR("thunderbolt-firewire"); interfacePrivate->localized_arg1 = slot_name; } else { interfacePrivate->localized_key = CFSTR("thunderbolt-multifirewire"); interfacePrivate->localized_arg1 = slot_name; interfacePrivate->localized_arg2 = port_name; } } else { if (port_name == NULL) { interfacePrivate->localized_key = CFSTR("pci-firewire"); interfacePrivate->localized_arg1 = slot_name; } else { interfacePrivate->localized_key = CFSTR("pci-multifirewire"); interfacePrivate->localized_arg1 = slot_name; interfacePrivate->localized_arg2 = port_name; } } } }
break; default : SC_log(LOG_INFO, "unknown interface type = %d", ift); return FALSE; }
// Device interfacePrivate->entity_device = IODictionaryCopyBSDName(interface_dict);
// Hardware (MAC) address data = CFDictionaryGetValue(controller_dict, CFSTR(kIOMACAddress)); if (isA_CFData(data)) { interfacePrivate->address = CFRetain(data); }
// interface prefix str = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceNamePrefix)); if (isA_CFString(str)) { interfacePrivate->prefix = CFRetain(str); }
// interface unit num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceUnit)); if (isA_CFNumber(num) && CFNumberGetValue(num, kCFNumberIntType, & iVal)) { interfacePrivate->unit = CFRetain(num); }
// configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides) merge_override(interfacePrivate, interface, kSCNetworkInterfaceTypePPP);
return TRUE;}
static voidset_connection_script(SCNetworkInterfacePrivateRef interfacePrivate, CFStringRef script){ CFDictionaryRef dict; CFMutableDictionaryRef newDict;
if (interfacePrivate->overrides == NULL) { interfacePrivate->overrides = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); }
dict = CFDictionaryGetValue(interfacePrivate->overrides, kSCNetworkInterfaceTypeModem); if (dict != NULL) { newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); } else { newDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } if (script != NULL) { CFDictionarySetValue(newDict, kSCPropNetModemConnectionScript, script); } else { CFDictionaryRemoveValue(newDict, kSCPropNetModemConnectionScript); } if (CFDictionaryGetCount(newDict) > 0) { CFDictionarySetValue(interfacePrivate->overrides, kSCNetworkInterfaceTypeModem, newDict); } else { CFDictionaryRemoveValue(interfacePrivate->overrides, kSCNetworkInterfaceTypeModem); } CFRelease(newDict);
if (CFDictionaryGetCount(interfacePrivate->overrides) == 0) { CFRelease(interfacePrivate->overrides); interfacePrivate->overrides = NULL; } return;}
static Booleanis_valid_connection_script(CFStringRef script){ char ccl[MAXPATHLEN]; char path[MAXPATHLEN]; sysdir_search_path_enumeration_state state;
(void) _SC_cfstring_to_cstring(script, ccl, sizeof(ccl), kCFStringEncodingUTF8);
state = sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY, SYSDIR_DOMAIN_MASK_LOCAL|SYSDIR_DOMAIN_MASK_SYSTEM); while ((state = sysdir_get_next_search_path_enumeration(state, path))) { size_t n; struct stat statBuf;
if (ccl[0] == '/') { path[0] = '\0'; // if modemCCL is a full path } else { strlcat(path, "/Modem Scripts/", sizeof(path)); } strlcat(path, ccl, sizeof(path));
if (stat(path, &statBuf) != 0) { if (errno == ENOENT) { goto bundle; }
SC_log(LOG_INFO, "stat() failed: %s", strerror(errno)); continue; } if (S_ISREG(statBuf.st_mode)) { // if we have a valid CCL script return TRUE; }
#define BUNDLE_EXT ".ccl"#define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
bundle :
n = strlen(path); if ((n <= BUNDLE_EXT_LEN) || (strstr(&path[n - BUNDLE_EXT_LEN], BUNDLE_EXT) == NULL)) { strlcat(path, BUNDLE_EXT, sizeof(path)); if (stat(path, &statBuf) != 0) { if (errno == ENOENT) { continue; }
SC_log(LOG_INFO, "stat() failed: %s", strerror(errno)); continue; } } if (S_ISDIR(statBuf.st_mode)) { // if we have a valid CCL bundle return TRUE; } }
return FALSE;}
static BooleanprocessSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t interface, CFDictionaryRef interface_dict, io_registry_entry_t controller, CFDictionaryRef controller_dict, io_registry_entry_t bus, CFDictionaryRef bus_dict){ CFStringRef base = NULL; CFStringRef ift; Boolean isModem = FALSE; Boolean isWWAN = FALSE; CFStringRef modemCCL = NULL; Boolean ok = FALSE; CFTypeRef val;
// check if initializing val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, kSCNetworkInterfaceInitializingKey, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { Boolean initializing;
initializing = isA_CFBoolean(val) && CFBooleanGetValue(val); CFRelease(val); if (initializing) { return FALSE; // if this interface is still initializing } }
// check if WWAN val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR("WWAN"), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { isWWAN = isA_CFBoolean(val) && CFBooleanGetValue(val); CFRelease(val); }
// Entity (Device) interfacePrivate->entity_device = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOTTYDeviceKey)); if (interfacePrivate->entity_device == NULL) { return FALSE; }
base = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOTTYBaseNameKey)); if (base == NULL) { base = CFRetain(interfacePrivate->entity_device); }
/* * From MoreSCF: * * Exclude ports named "irda" because otherwise the IrDA ports on the * original iMac (rev's A through D) show up as serial ports. Given * that only the rev A actually had an IrDA port, and Mac OS X doesn't * even support it, these ports definitely shouldn't be listed. */ if (CFStringCompare(base, CFSTR("irda"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { goto done; }
if (IOStringValueHasPrefix(base, CFSTR("bluetooth"))) { Boolean haveController = FALSE;
// Bluetooth interfacePrivate->interface_type = kSCNetworkInterfaceTypeBluetooth; interfacePrivate->sort_order = kSortBluetooth; interfacePrivate->builtin = isBluetoothBuiltin(&haveController); if (!haveController) { // if device with no controller present goto done; } } else if (IOStringValueHasPrefix(base, CFSTR("irda-ircomm"))) { // IrDA interfacePrivate->interface_type = kSCNetworkInterfaceTypeIrDA; interfacePrivate->sort_order = kSortIrDA; } else if (isWWAN) { // WWAN interfacePrivate->interface_type = kSCNetworkInterfaceTypeWWAN; interfacePrivate->sort_order = kSortWWAN; } else { // Modem interfacePrivate->interface_type = kSCNetworkInterfaceTypeModem; interfacePrivate->sort_order = kSortModem; }
// Entity (Type) interfacePrivate->entity_type = kSCEntNetModem;
// Entity (Hardware) ift = CFDictionaryGetValue(interface_dict, CFSTR(kIOSerialBSDTypeKey)); if (!isA_CFString(ift)) { goto done; }
if (CFEqual(ift, CFSTR(kIOSerialBSDModemType))) { // if modem isModem = TRUE;
if (CFEqual(base, CFSTR("modem"))) { interfacePrivate->builtin = TRUE; interfacePrivate->sort_order = kSortInternalModem; } else if (CFEqual(base, CFSTR("usbmodem"))) { interfacePrivate->sort_order = kSortUSBModem; } } else if (CFEqual(ift, CFSTR(kIOSerialBSDRS232Type))) { // if serial port interfacePrivate->sort_order = kSortSerialPort; } else { goto done; }
// configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides) merge_override(interfacePrivate, interface, kSCNetworkInterfaceTypePPP);
// configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides) merge_override(interfacePrivate, interface, kSCNetworkInterfaceTypeModem);
// look for modem CCL, unique identifier if (interfacePrivate->overrides != NULL) { val = CFDictionaryGetValue(interfacePrivate->overrides, kSCNetworkInterfaceTypeModem); if (val != NULL) { CFStringRef uniqueID;
modemCCL = CFDictionaryGetValue(val, kSCPropNetModemConnectionScript); modemCCL = isA_CFString(modemCCL);
uniqueID = CFDictionaryGetValue(val, CFSTR("UniqueIdentifier")); uniqueID = isA_CFString(uniqueID); if (uniqueID != NULL) { // retain the device's base name and the unique id CFRelease(interfacePrivate->entity_device); interfacePrivate->entity_device = CFRetain(base); interfacePrivate->entity_device_unique = CFStringCreateCopy(NULL, uniqueID); } } }
// if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look // a bit harder for the modem CCL if (modemCCL == NULL) { val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR("ModemCCL"), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { modemCCL = IOCopyCFStringValue(val); if (modemCCL != NULL) { set_connection_script(interfacePrivate, modemCCL); CFRelease(modemCCL); }
CFRelease(val); } }
// localized name if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIrDA)) { interfacePrivate->localized_key = CFSTR("irda"); } else if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeBluetooth)) { interfacePrivate->localized_key = CFSTR("bluetooth"); } else { CFStringRef localized = NULL; CFStringRef name = NULL; CFMutableStringRef port;
port = CFStringCreateMutableCopy(NULL, 0, base); CFStringLowercase(port, NULL);
if (!isModem) { CFStringAppend(port, CFSTR("-port")); }
// set non-localized name if (bundle != NULL) { name = copy_interface_string(bundle, port, FALSE); } if (name != NULL) { if (!CFEqual(port, name)) { // if [English] localization available interfacePrivate->name = name; } else { // if no [English] localization available, use TTY base name CFRelease(name); interfacePrivate->name = CFStringCreateCopy(NULL, base); } } else { interfacePrivate->name = CFStringCreateCopy(NULL, base); }
// set localized name if (bundle != NULL) { localized = copy_interface_string(bundle, port, TRUE); } if (localized != NULL) { if (!CFEqual(port, localized)) { // if localization available interfacePrivate->localized_name = localized; } else { // if no localization available, use TTY base name CFRelease(localized); interfacePrivate->localized_name = CFStringCreateCopy(NULL, base); } } else { interfacePrivate->localized_name = CFStringCreateCopy(NULL, base); }
if (!isModem || !CFEqual(base, CFSTR("modem"))) { // get USB info (if available) processUSBInterface(interfacePrivate, interface, interface_dict, controller, controller_dict, bus, bus_dict);
// set interface "name" if (update_interface_name(interfacePrivate, interface, TRUE)) { // if "ModemCCL" not provided, also check if the product/interface // name matches a CCL script if ((modemCCL == NULL) && is_valid_connection_script(interfacePrivate->name)) { set_connection_script(interfacePrivate, interfacePrivate->name); } } }
CFRelease(port); }
ok = TRUE;
done :
if (!ok && (interfacePrivate->entity_device != NULL)) { CFRelease(interfacePrivate->entity_device); interfacePrivate->entity_device = NULL; } if (base != NULL) CFRelease(base);
return ok;}
static CFStringRef__SC_IORegistryEntryCopyPath(io_registry_entry_t entry, const io_name_t plane){ /* * Create a path for a registry entry. */ io_string_t path; IOReturn status; CFStringRef str = NULL;
status = IORegistryEntryGetPath(entry, plane, path); if (status == kIOReturnSuccess) { str = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8); } else if (status == kIOReturnBadArgument) { io_registry_entry_t parent;
status = IORegistryEntryGetParentEntry(entry, plane, &parent); if (status == kIOReturnSuccess) { CFStringRef str_parent;
str_parent = __SC_IORegistryEntryCopyPath(parent, plane); if (str_parent != NULL) { io_name_t name;
status = IORegistryEntryGetNameInPlane(entry, plane, name); if (status == kIOReturnSuccess) { io_name_t location;
status = IORegistryEntryGetLocationInPlane(entry, plane, location); if (status == kIOReturnSuccess) { str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%s@%s"), str_parent, name, location); } else { str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%s"), str_parent, name); } }
CFRelease(str_parent); }
IOObjectRelease(parent); } }
return str;}
static CFMutableDictionaryRefcopyIORegistryProperties(io_registry_entry_t reg_ent, const CFStringRef *reg_keys, CFIndex numKeys){ CFIndex idx = 0; CFMutableDictionaryRef reg_dict = NULL; CFTypeRef value = NULL;
reg_dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks , &kCFTypeDictionaryValueCallBacks);
for (; idx < numKeys; idx++) { value = IORegistryEntryCreateCFProperty(reg_ent, reg_keys[idx], NULL, 0); if (value != NULL) { CFDictionaryAddValue(reg_dict, reg_keys[idx], value); CFRelease(value); } }
return reg_dict;}
static SCNetworkInterfaceRefcreateInterface(io_registry_entry_t interface, processInterface func, CFStringRef hidden_key){ io_registry_entry_t bus = MACH_PORT_NULL; CFMutableDictionaryRef bus_dict = NULL; io_registry_entry_t controller = MACH_PORT_NULL; CFMutableDictionaryRef controller_dict = NULL; uint64_t entryID = 0; SCNetworkInterfacePrivateRef interfacePrivate = NULL; CFMutableDictionaryRef interface_dict = NULL; kern_return_t kr; CFTypeRef val;
// Keys of interest const CFStringRef interface_dict_keys[] = { CFSTR(kIOInterfaceType), CFSTR(kIOBuiltin), CFSTR(kIOBSDNameKey), CFSTR(kIOPrimaryInterface), CFSTR(kIOInterfaceNamePrefix), CFSTR(kIOInterfaceUnit), CFSTR(kIOTTYDeviceKey), CFSTR(kIOTTYBaseNameKey), CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOLocation) };
const CFStringRef controller_dict_keys[] = { CFSTR(kIOFeatures), CFSTR(kIOMACAddress) };
const CFStringRef bus_dict_keys[] = { CFSTR("name") };
if (hidden_key != NULL) { // check if hidden val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, hidden_key, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { CFRelease(val); goto done; // if this interface should not be exposed } }
interface_dict = copyIORegistryProperties(interface, interface_dict_keys, sizeof(interface_dict_keys)/sizeof(interface_dict_keys[0]));
// get the controller node kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &controller); if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr); goto done; }
controller_dict = copyIORegistryProperties(controller, controller_dict_keys, sizeof(controller_dict_keys)/sizeof(controller_dict_keys[0]));
// get the bus node kr = IORegistryEntryGetParentEntry(controller, kIOServicePlane, &bus); if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr); goto done; }
bus_dict = copyIORegistryProperties(bus, bus_dict_keys, sizeof(bus_dict_keys)/sizeof(bus_dict_keys[0]));
// get the registry entry ID kr = IORegistryEntryGetRegistryEntryID(interface, &entryID); if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr); goto done; }
interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL); assert(interfacePrivate != NULL); interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane); interfacePrivate->entryID = entryID;
// configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, kSCNetworkInterfaceNetworkConfigurationOverridesKey, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { if (isA_CFDictionary(val)) { interfacePrivate->overrides = CFDictionaryCreateMutableCopy(NULL, 0, val); } CFRelease(val); }
if ((*func)(interfacePrivate, interface, interface_dict, controller, controller_dict, bus, bus_dict)) { // get user-notification / auto-configuration preference val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, kSCNetworkInterfaceConfigurationActionKey, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { if (isA_CFString(val)) { interfacePrivate->configurationAction = CFRetain(val); } CFRelease(val); }
// get HiddenConfiguration preference val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, kSCNetworkInterfaceHiddenConfigurationKey, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { interfacePrivate->hidden = TRUE; CFRelease(val); }
#if TARGET_OS_IPHONE // get TrustRequired preference val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, kSCNetworkInterfaceTrustRequiredKey, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { if (isA_CFBoolean(val)) { interfacePrivate->trustRequired = CFBooleanGetValue(val); } CFRelease(val); }#endif // TARGET_OS_IPHONE } else { CFRelease(interfacePrivate); interfacePrivate = NULL; }
done :
if (interface_dict != NULL) CFRelease(interface_dict);
if (controller != MACH_PORT_NULL) IOObjectRelease(controller); if (controller_dict != NULL) CFRelease(controller_dict);
if (bus != MACH_PORT_NULL) IOObjectRelease(bus); if (bus_dict != NULL) CFRelease(bus_dict);
return (SCNetworkInterfaceRef)interfacePrivate;}
static CF_RETURNS_RETAINED CFArrayReffindMatchingInterfaces(CFDictionaryRef matching, processInterface func, CFStringRef hidden_key, Boolean keep_pre_configured){ CFMutableArrayRef interfaces; io_registry_entry_t interface; kern_return_t kr; io_iterator_t iterator = MACH_PORT_NULL;
/* * A reference to the "matching" dictionary will be consumed by the * the call to IOServiceGetMatchingServices so we bump up the retain * count. */ CFRetain(matching);
kr = IOServiceGetMatchingServices(masterPort, matching, &iterator); if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr); return NULL; }
interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
while ((interface = IOIteratorNext(iterator)) != MACH_PORT_NULL) { SCNetworkInterfaceRef match;
match = createInterface(interface, func, hidden_key); if (match != NULL) { if (keep_pre_configured || !_SCNetworkInterfaceIsApplePreconfigured(match)) { CFArrayAppendValue(interfaces, match); } CFRelease(match); }
IOObjectRelease(interface); }
IOObjectRelease(iterator);
return interfaces;}
#pragma mark -#pragma mark helper functions
static CFIndexfindConfiguration(CFStringRef interface_type){ for (size_t i = 0; i < sizeof(configurations)/sizeof(configurations[0]); i++) { if (CFEqual(interface_type, *configurations[i].interface_type)) { return i; } }
return kCFNotFound;}
__private_extern__CFStringRef__SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface){ CFIndex interfaceIndex; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (interfacePrivate->serviceID == NULL) { // if not associated with a service (yet) _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
interfaceIndex = findConfiguration(interfacePrivate->interface_type); if (interfaceIndex == kCFNotFound) { // unknown interface type, use per-service configuration preferences return interfacePrivate->interface_type; // entity }
if (configurations[interfaceIndex].entity_hardware != NULL) { // if configuration information can be associated with this interface type return *configurations[interfaceIndex].entity_hardware; }
_SCErrorSet(kSCStatusInvalidArgument); return NULL;}
__private_extern__Boolean__SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface, CFStringRef extendedType, Boolean requirePerInterface){ CFStringRef defaultType; CFIndex extendedIndex; CFIndex interfaceIndex; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; Boolean isL2TP = FALSE; Boolean ok = FALSE;
defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType == NULL) { goto done; }
if (CFEqual(extendedType, defaultType)) { // extended and default configuration types cannot conflict goto done; }
interfaceIndex = findConfiguration(interfacePrivate->interface_type); if (interfaceIndex == kCFNotFound) { // configuration information for unknown interface type's // are stored along with the service and we don't allow // per-service extended configurations goto done; }
if (CFEqual(extendedType, kSCEntNetIPSec)) { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) { SCNetworkInterfaceRef child;
child = SCNetworkInterfaceGetInterface(interface); if (child != NULL) { interfaceType = SCNetworkInterfaceGetInterfaceType(child); if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) { isL2TP = TRUE; } } } }
if (requirePerInterface && !configurations[interfaceIndex].per_interface_config && !isL2TP) { // we don't allow per-service extended configurations (except // that we do allow IPSec as an extended type for PPP->L2TP) goto done; }
extendedIndex = findConfiguration(extendedType); if ((extendedIndex != kCFNotFound) && !isL2TP) { // extended type cannot match a known interface type (except // that we do allow IPSec as an extended type for PPP->L2TP) goto done; }
/* * ??? * Should we check/match and specifically allow known extended * configuration types (e.g. EAPOL)? * * Should we check/match and specifically block known internal * configuration types (e.g. QoSMarking)? * * Lastly, should we ensure that any non-standard extended configuration * types be of the form com.myCompany.myType? * ??? */
ok = TRUE;
done :
if (!ok) { _SCErrorSet(kSCStatusInvalidArgument); } return ok;}
typedef struct { CFStringRef defaultType; CFMutableArrayRef types;} extendedConfiguration, *extendedConfigurationRef;
static void__addExtendedConfigurationType(const void *key, const void *value, void *context){#pragma unused(value) CFStringRef extendedType = (CFStringRef)key; extendedConfigurationRef myContextRef = (extendedConfigurationRef)context;
if (CFEqual(extendedType, myContextRef->defaultType)) { // do not include the default configuration type return; }
if (CFArrayContainsValue(myContextRef->types, CFRangeMake(0, CFArrayGetCount(myContextRef->types)), extendedType)) { // if extendedType already has already been added return; }
CFArrayAppendValue(myContextRef->types, extendedType);
return;}
static CFIndexfindPerInterfaceConfiguration(SCNetworkInterfaceRef interface){ CFIndex interfaceIndex; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
interfaceIndex = findConfiguration(interfacePrivate->interface_type); if (interfaceIndex == kCFNotFound) { // if per-service (not per interface) configuration return kCFNotFound; }
if (!configurations[interfaceIndex].per_interface_config) { // if per-interface configuration not allowed return kCFNotFound; }
return interfaceIndex;}
static CF_RETURNS_RETAINED CFArrayRefextendedConfigurationTypes(SCNetworkInterfaceRef interface){ CFIndex i; CFIndex interfaceIndex; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; extendedConfiguration myContext; SCNetworkServiceRef service; CFArrayRef sets; CFIndex n;
myContext.defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (myContext.defaultType == NULL) { myContext.types = NULL; goto done; }
myContext.types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
if (interfacePrivate->serviceID == NULL) { // if not associated with a service (yet) goto done; }
interfaceIndex = findPerInterfaceConfiguration(interface); if (interfaceIndex == kCFNotFound) { // if no per-interface configuration goto done; }
service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL, interfacePrivate->prefs, interfacePrivate->serviceID, interface);
sets = SCNetworkSetCopyAll(interfacePrivate->prefs); n = (sets != NULL) ? CFArrayGetCount(sets) : 0;
for (i = 0; i < n; i++) { CFDictionaryRef configs; Boolean found; CFStringRef path; CFArrayRef services; SCNetworkSetRef set;
set = CFArrayGetValueAtIndex(sets, i); services = SCNetworkSetCopyServices(set); found = CFArrayContainsValue(services, CFRangeMake(0, CFArrayGetCount(services)), service); CFRelease(services);
if (!found) { continue; }
// add stored extended configuration types path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL, // allocator SCNetworkSetGetSetID(set), // set interfacePrivate->entity_device, // service NULL); // entity configs = __getPrefsConfiguration(interfacePrivate->prefs, path); CFRelease(path); if (isA_CFDictionary(configs)) { CFDictionaryApplyFunction(configs, __addExtendedConfigurationType, &myContext); }
// add not-yet-stored extended configuration types if (interfacePrivate->unsaved != NULL) { CFDictionaryApplyFunction(interfacePrivate->unsaved, __addExtendedConfigurationType, &myContext); }
break; }
CFRelease(service); if (sets != NULL) CFRelease(sets);
done :
return myContext.types;}
static CFArrayRefstringCreateArray(CFStringRef str){ return (CFArrayCreate(NULL, (const void **)&str, 1, &kCFTypeArrayCallBacks));}
static CFArrayRefcopyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate, CFStringRef extendedType){ CFMutableArrayRef array = NULL; CFIndex i; CFIndex n; CFStringRef path; SCNetworkServiceRef service; CFArrayRef sets;
// known interface type, per-interface configuration preferences // // 1. look for all sets which contain the associated service // 2. add a per-set path for the interface configuration for // each set.
service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL, interfacePrivate->prefs, interfacePrivate->serviceID, (SCNetworkInterfaceRef)interfacePrivate);
sets = SCNetworkSetCopyAll(interfacePrivate->prefs); n = (sets != NULL) ? CFArrayGetCount(sets) : 0;
for (i = 0; i < n; i++) { CFArrayRef services; SCNetworkSetRef set;
set = CFArrayGetValueAtIndex(sets, i); services = SCNetworkSetCopyServices(set); if (CFArrayContainsValue(services, CFRangeMake(0, CFArrayGetCount(services)), service)) { path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL, // allocator SCNetworkSetGetSetID(set), // set interfacePrivate->entity_device, // service extendedType); // entity if (array == NULL) { array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(array, path); CFRelease(path); } CFRelease(services); }
CFRelease(service); if (sets != NULL) CFRelease(sets); return array;
}
static CFArrayRefcopyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate, CFStringRef extendedType){ CFArrayRef array = NULL; CFIndex interfaceIndex; CFStringRef path;
interfaceIndex = findConfiguration(interfacePrivate->interface_type); if (interfaceIndex == kCFNotFound) { // unknown interface type, use per-service configuration preferences path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator interfacePrivate->serviceID, // service extendedType); // entity array = stringCreateArray(path); CFRelease(path); }
else if (!configurations[interfaceIndex].per_interface_config) { // known interface type, per-service configuration preferences path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator interfacePrivate->serviceID, // service extendedType); // entity array = stringCreateArray(path); CFRelease(path); }
else if (interfacePrivate->serviceID != NULL) { array = copyPerInterfaceConfigurationPaths(interfacePrivate, extendedType); }
return (array);}
#pragma mark -#pragma mark SCNetworkInterface <--> preferences entity
__private_extern__CFDictionaryRef__SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface){ CFMutableDictionaryRef entity; CFIndex interfaceIndex; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
entity = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (interfacePrivate->entity_type != NULL) { CFDictionarySetValue(entity, kSCPropNetInterfaceType, interfacePrivate->entity_type); } if (interfacePrivate->entity_subtype != NULL) { CFDictionarySetValue(entity, kSCPropNetInterfaceSubType, interfacePrivate->entity_subtype); } if (interfacePrivate->entity_device != NULL) { CFDictionarySetValue(entity, kSCPropNetInterfaceDeviceName, interfacePrivate->entity_device); } if (interfacePrivate->entity_device_unique != NULL) { CFDictionarySetValue(entity, CFSTR("DeviceUniqueIdentifier"), interfacePrivate->entity_device_unique); } if (interfacePrivate->hidden) { CFDictionarySetValue(entity, kSCNetworkInterfaceHiddenConfigurationKey, kCFBooleanTrue); }#if TARGET_OS_IPHONE if (interfacePrivate->trustRequired) { CFDictionarySetValue(entity, kSCNetworkInterfaceTrustRequiredKey, kCFBooleanTrue); }#endif // TARGET_OS_IPHONE
// match the "hardware" with the lowest layer while (TRUE) { SCNetworkInterfaceRef nextInterface;
nextInterface = SCNetworkInterfaceGetInterface(interface); if (nextInterface == NULL) { break; }
interface = nextInterface; } interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (CFEqual(interface, kSCNetworkInterfaceIPv4)) { return entity; }
interfaceIndex = findConfiguration(interfacePrivate->interface_type); if (interfaceIndex != kCFNotFound) { if (configurations[interfaceIndex].entity_hardware != NULL) { CFDictionarySetValue(entity, kSCPropNetInterfaceHardware, *configurations[interfaceIndex].entity_hardware); } } else { CFDictionarySetValue(entity, kSCPropNetInterfaceHardware, interfacePrivate->interface_type); }
// add the localized display name (which will only be used when/if the // interface is removed from the system) CFDictionarySetValue(entity, kSCPropUserDefinedName, SCNetworkInterfaceGetLocalizedDisplayName(interface));
return entity;}
static SCNetworkInterfaceReffindInterface(CFArrayRef interfaces, CFStringRef match_if){ CFIndex i; CFIndex n;
n = CFArrayGetCount(interfaces); for (i = 0; i < n; i++) { SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(interfaces, i); CFStringRef interfaceName;
interfaceName = SCNetworkInterfaceGetBSDName(interface); if ((interfaceName != NULL) && CFEqual(interfaceName, match_if)) { CFRetain(interface); return interface; } }
return NULL;}
#if !TARGET_OS_IPHONEstatic SCNetworkInterfaceReffindBondInterface(SCPreferencesRef prefs, CFStringRef ifDevice){ CFArrayRef bonds; SCNetworkInterfaceRef interface = NULL;
if (prefs == NULL) { return (NULL); }
// check if the interface is an Ethernet Bond bonds = SCBondInterfaceCopyAll(prefs); if (bonds != NULL) { interface = findInterface(bonds, ifDevice); CFRelease(bonds); } return interface;}#endif // !TARGET_OS_IPHONE
static SCNetworkInterfaceReffindBridgeInterface(SCPreferencesRef prefs, CFStringRef ifDevice){ CFArrayRef bridges; SCNetworkInterfaceRef interface = NULL;
if (prefs == NULL) { return (NULL); }
// check if the interface is an bridge bridges = SCBridgeInterfaceCopyAll(prefs); if (bridges != NULL) { interface = findInterface(bridges, ifDevice); CFRelease(bridges); } return interface;}
static SCNetworkInterfaceReffindVLANInterface(SCPreferencesRef prefs, CFStringRef ifDevice){ SCNetworkInterfaceRef interface = NULL; CFArrayRef vlans;
if (prefs == NULL) { return (NULL); }
// check if the interface is a VLAN vlans = SCVLANInterfaceCopyAll(prefs); if (vlans != NULL) { interface = findInterface(vlans, ifDevice); CFRelease(vlans); } return interface;}
#define N_QUICK 32
static CFMutableDictionaryRefcopy_ppp_entity(CFStringRef bsdName){ CFMutableDictionaryRef entity = NULL; CFStringRef pattern; CFMutableArrayRef patterns; CFDictionaryRef dict;
patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetPPP); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetInterface); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); dict = SCDynamicStoreCopyMultiple(NULL, NULL, patterns); CFRelease(patterns); if (dict != NULL) { CFIndex i; const void * keys_q[N_QUICK]; const void ** keys = keys_q; CFIndex n; const void * vals_q[N_QUICK]; const void ** vals = vals_q;
n = CFDictionaryGetCount(dict); if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) { keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0); vals = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0); } CFDictionaryGetKeysAndValues(dict, keys, vals); for (i = 0; i < n; i++) { CFArrayRef components; CFStringRef interfaceKey; CFDictionaryRef interfaceVal; CFStringRef ifName; CFStringRef pppKey = (CFStringRef)keys[i]; CFDictionaryRef pppVal = (CFDictionaryRef)vals[i]; CFStringRef serviceID;
if (!CFStringHasSuffix(pppKey, kSCEntNetPPP) || !CFDictionaryGetValueIfPresent(pppVal, kSCPropInterfaceName, (const void **)&ifName) || !CFEqual(bsdName, ifName)) { // if not matching PPP interface continue; }
components = CFStringCreateArrayBySeparatingStrings(NULL, pppKey, CFSTR("/")); serviceID = CFArrayGetValueAtIndex(components, 3); interfaceKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, serviceID, kSCEntNetInterface); interfaceVal = CFDictionaryGetValue(dict, interfaceKey); CFRelease(interfaceKey); CFRelease(components); if (interfaceVal != NULL) { entity = CFDictionaryCreateMutableCopy(NULL, 0, interfaceVal); break; } } if (keys != keys_q) { CFAllocatorDeallocate(NULL, keys); CFAllocatorDeallocate(NULL, vals); }
CFRelease(dict); }
return entity;}
SCNetworkInterfaceRef_SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator, CFStringRef bsdName, UInt32 flags){#pragma unused(allocator) CFMutableDictionaryRef entity = NULL; struct ifreq ifr; SCNetworkInterfaceRef interface;
memset(&ifr, 0, sizeof(ifr)); if (_SC_cfstring_to_cstring(bsdName, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) != NULL) { int s;
s = socket(AF_INET, SOCK_DGRAM, 0); if (s != -1) { if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) { ifr.ifr_flags = 0; } close(s); }
if ((ifr.ifr_flags & IFF_POINTOPOINT) != 0) { // if PPP entity = copy_ppp_entity(bsdName); } }
if (entity == NULL) { entity = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(entity, kSCPropNetInterfaceDeviceName, bsdName); }
#if !TARGET_OS_IPHONE if ((flags & kIncludeBondInterfaces) == 0) { CFDictionarySetValue(entity, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue); }#endif // !TARGET_OS_IPHONE
if ((flags & kIncludeBridgeInterfaces) == 0) { CFDictionarySetValue(entity, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue); }
if ((flags & kIncludeVLANInterfaces) == 0) { CFDictionarySetValue(entity, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue); }
interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, NULL); CFRelease(entity);
return interface;}
static CFStringRef_SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName){ CFMutableStringRef interfacePrefix = NULL; UniChar lastChar; CFIndex length = 0;
if (isA_CFString(bsdName) == NULL) { SC_log(LOG_DEBUG, "no BSD name"); goto done; }
interfacePrefix = CFStringCreateMutableCopy(NULL, 0, bsdName); length = CFStringGetLength(interfacePrefix);
while (length > 0) { lastChar = CFStringGetCharacterAtIndex(interfacePrefix, length - 1); if (lastChar >= '0' && lastChar <= '9') { CFStringDelete(interfacePrefix, CFRangeMake(length-1, 1)); } else { break; } length = CFStringGetLength(interfacePrefix); }done: return interfacePrefix;}
static void__SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface, CFStringRef prefix);
static Boolean__SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface, CFStringRef currentBSDName, CFStringRef newBSDName){ Boolean success = FALSE; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (isA_SCNetworkInterface(interface) == NULL) { SC_log(LOG_INFO, "No interface"); goto done; }
if (CFEqual(currentBSDName, newBSDName)) { // if no change goto done; }
if (interfacePrivate->entity_device != NULL) { CFRelease(interfacePrivate->entity_device); } interfacePrivate->entity_device = CFRetain(newBSDName); success = TRUE;done: return success;}
static Boolean__SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface){ Boolean success = FALSE; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFStringRef oldPath = NULL; CFStringRef newPath = NULL;
// Using the BSD Name update the path oldPath = interfacePrivate->path; if (isA_CFString(oldPath) == NULL) { goto done; } newPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("Migrated_From: %@"), oldPath); if (interfacePrivate->path != NULL) { CFRelease(interfacePrivate->path); } interfacePrivate->path = CFRetain(newPath); success = TRUE;
done: if (newPath != NULL) { CFRelease(newPath); } return success;}
static void__SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface, CFStringRef prefix){ SCNetworkInterfacePrivateRef interfacePrivate;
if (isA_CFString(prefix) == NULL) { return; }
interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
CFRetain(prefix);
if (interfacePrivate->prefix != NULL) { CFRelease(interfacePrivate->prefix); }
interfacePrivate->prefix = prefix; return;}
__private_extern__void__SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface, CFNumberRef unit){ SCNetworkInterfacePrivateRef interfacePrivate; CFStringRef newBSDName = NULL; CFStringRef oldBSDName = NULL;
if (isA_CFNumber(unit) == NULL) { return; } interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
oldBSDName = SCNetworkInterfaceGetBSDName(interface);
if (interfacePrivate->prefix == NULL) { if (isA_CFString(interfacePrivate->entity_device) != NULL) { CFStringRef interfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate->entity_device); if (interfaceNamePrefix == NULL) { SC_log(LOG_INFO, "interfaceNamePrefix is NULL"); } else { __SCNetworkInterfaceSetIOInterfacePrefix(interface, interfaceNamePrefix); CFRelease(interfaceNamePrefix); } } }
if (interfacePrivate->prefix != NULL) { newBSDName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), interfacePrivate->prefix, unit); }
// Update the BSD Name if ((newBSDName == NULL) || (!__SCNetworkInterfaceUpdateBSDName(interface, oldBSDName, newBSDName))) { SC_log(LOG_INFO, "BSD name update failed"); }
// Update the path if (!__SCNetworkInterfaceUpdateIOPath(interface)) { SC_log(LOG_INFO, "IOPath update failed"); }
CFRetain(unit); if (interfacePrivate->unit != NULL) { CFRelease(interfacePrivate->unit); } interfacePrivate->unit = unit;
if (newBSDName != NULL) { CFRelease(newBSDName); } return;}
__private_extern__CFDictionaryRef__SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface){ CFMutableDictionaryRef interface_entity = NULL; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFBooleanRef active = NULL; CFStringRef bsdName = NULL; CFBooleanRef builtin = NULL; CFStringRef interfaceNamePrefix = NULL; CFNumberRef interfaceType = NULL; CFNumberRef interfaceUnit = NULL; CFDataRef macAddress = NULL; CFStringRef pathMatch = NULL; CFDictionaryRef info = NULL; CFStringRef type = NULL;
if (interfacePrivate->active) { active = kCFBooleanTrue; }
bsdName = SCNetworkInterfaceGetBSDName(interface); if (!isA_CFString(bsdName)) { goto done; }
builtin = interfacePrivate->builtin ? kCFBooleanTrue : kCFBooleanFalse; interfaceNamePrefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface); if (!isA_CFString(interfaceNamePrefix)) { goto done; }
interfaceType = _SCNetworkInterfaceGetIOInterfaceType(interface); if (!isA_CFNumber(interfaceType)) { goto done; }
interfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(interface); if (!isA_CFNumber(interfaceUnit)) { goto done; }
macAddress = _SCNetworkInterfaceGetHardwareAddress(interface); if (!isA_CFData(macAddress)) { goto done; }
pathMatch = _SCNetworkInterfaceGetIOPath(interface); if (!isA_CFString(pathMatch)) { goto done; }
info = _SCNetworkInterfaceCopyInterfaceInfo(interface); if (!isA_CFDictionary(info)) { goto done; }
type = SCNetworkInterfaceGetInterfaceType(interface); if (!isA_CFString(type)) { goto done; }
interface_entity = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (isA_CFBoolean(active) != NULL) { CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), active); }
CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName), bsdName); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin), builtin); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix), interfaceNamePrefix); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType), interfaceType); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit), interfaceUnit); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress), macAddress); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch), pathMatch); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo), info); CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceType), type);done: if (info != NULL) { CFRelease(info); } return interface_entity;}
static void__SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface, SCNetworkServiceRef service){ SCNetworkInterfacePrivateRef interfacePrivate; SCNetworkServicePrivateRef servicePrivate;
interfacePrivate = (SCNetworkInterfacePrivateRef)interface; if (interfacePrivate->prefs != NULL) { CFRelease(interfacePrivate->prefs); interfacePrivate->prefs = NULL; } if (interfacePrivate->serviceID != NULL) { CFRelease(interfacePrivate->serviceID); interfacePrivate->serviceID = NULL; }
servicePrivate = (SCNetworkServicePrivateRef)service; if (servicePrivate->prefs != NULL) { interfacePrivate->prefs = CFRetain(servicePrivate->prefs); } if (servicePrivate->serviceID != NULL) { interfacePrivate->serviceID = CFRetain(servicePrivate->serviceID); }
return;}
__private_extern__Boolean__SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key){ Boolean match; CFStringRef str;
if (bundle == NULL) { SC_log(LOG_NOTICE, "no bundle information to compare interface names"); return FALSE; }
if (!isA_CFString(name)) { // if no interface "name" return FALSE; }
// check non-localized name for a match str = copy_interface_string(bundle, key, FALSE); if (str != NULL) { match = CFEqual(name, str); CFRelease(str); if (match) { return TRUE; } }
// check localized name for a match str = copy_interface_string(bundle, key, TRUE); if (str != NULL) { match = CFEqual(name, str); CFRelease(str); if (match) { return TRUE; } }
return FALSE;}
#define kInterfaceTypeEthernetValue 6#define kInterfaceTypeFirewireValue 144
static SCNetworkInterfaceRef__SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator, CFDictionaryRef interface_entity){#pragma unused(allocator) SCNetworkInterfacePrivateRef interfacePrivate = NULL; CFBooleanRef active = NULL; CFStringRef bsdName = NULL; CFBooleanRef ioBuiltin = NULL; CFStringRef ioInterfaceNamePrefix = NULL; CFNumberRef ioInterfaceType = NULL; int ioInterfaceTypeNum; CFNumberRef ioInterfaceUnit = NULL; CFDataRef ioMACAddress = NULL; CFStringRef ioPathMatch = NULL; CFDictionaryRef SCNetworkInterfaceInfo = NULL; CFStringRef userDefinedName = NULL; CFStringRef usbProductName = NULL; CFNumberRef idProduct = NULL; CFNumberRef idVendor = NULL; CFStringRef type = NULL;
/* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (isA_CFDictionary(interface_entity) == NULL) { SC_log(LOG_INFO, "No interface entity"); goto done; } active = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceActive)); if (isA_CFBoolean(active) == NULL) { active = kCFBooleanFalse; } bsdName = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName)); if (isA_CFString(bsdName) == NULL) { SC_log(LOG_INFO, "No BSD name"); goto done; } ioBuiltin = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin)); if (isA_CFBoolean(ioBuiltin) == NULL) { SC_log(LOG_INFO, "No IOBuiltin property"); goto done; } ioInterfaceNamePrefix = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix)); if (isA_CFString(ioInterfaceNamePrefix) == NULL) { ioInterfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName); if (ioInterfaceNamePrefix == NULL) { SC_log(LOG_INFO, "No BSD interface name prefix"); goto done; } } else { CFRetain(ioInterfaceNamePrefix); } ioInterfaceType = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType)); if (isA_CFNumber(ioInterfaceType) == NULL) { SC_log(LOG_INFO, "No IOInterfaceType"); goto done; } if (!CFNumberGetValue(ioInterfaceType, kCFNumberIntType, &ioInterfaceTypeNum)) { SC_log(LOG_NOTICE, "Count not extract value from ioInterfaceType"); } ioInterfaceUnit = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit)); if (isA_CFNumber(ioInterfaceUnit) == NULL) { SC_log(LOG_INFO, "No IOInterfaceUnit");
goto done; } ioMACAddress = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress)); if (isA_CFData(ioMACAddress) == NULL) { SC_log(LOG_INFO, "No IOMACAddress"); goto done; } ioPathMatch = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch)); if (isA_CFString(ioPathMatch) == NULL) { SC_log(LOG_INFO, "No IOPathMatch"); goto done; } else { // Check if Path contains the BSD Name in the end } SCNetworkInterfaceInfo = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo)); if (isA_CFDictionary(SCNetworkInterfaceInfo) == NULL) { SC_log(LOG_INFO, "No SCNetworkInterfaceInfo"); goto done; } userDefinedName = CFDictionaryGetValue(SCNetworkInterfaceInfo, kSCPropUserDefinedName);#if !TARGET_OS_SIMULATOR usbProductName = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductString)); idProduct = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductID)); idVendor = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBVendorID));#endif // !TARGET_OS_SIMULATOR
type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType)); if (isA_CFString(type) == NULL) { SC_log(LOG_INFO, "No SCNetworkInterfaceType"); goto done; }
interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL); interfacePrivate->active = CFBooleanGetValue(active); interfacePrivate->entity_device = CFRetain(bsdName); interfacePrivate->builtin = CFBooleanGetValue(ioBuiltin); interfacePrivate->prefix = CFRetain(ioInterfaceNamePrefix); interfacePrivate->type = CFRetain(ioInterfaceType); interfacePrivate->unit = CFRetain(ioInterfaceUnit); interfacePrivate->address = CFRetain(ioMACAddress); interfacePrivate->path = CFRetain(ioPathMatch); interfacePrivate->name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL); interfacePrivate->localized_name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL); interfacePrivate->usb.name = ((usbProductName != NULL) ? CFRetain(usbProductName) : NULL); interfacePrivate->usb.pid = ((idProduct != NULL) ? CFRetain(idProduct) : NULL); interfacePrivate->usb.vid = ((idVendor != NULL) ? CFRetain(idVendor) : NULL);
// Handling interface types to be seen in NetworkInterfaces.plist CFIndex interfaceIndex;
interfaceIndex = findConfiguration(type); if (interfaceIndex != kCFNotFound) { interfacePrivate->interface_type = *configurations[interfaceIndex].interface_type; } else { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; }
// Extracting entity type from value of interface type if (ioInterfaceTypeNum == kInterfaceTypeEthernetValue) { interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; // kSCNetworkInterfaceTypeEthernet; } else if (ioInterfaceTypeNum == kInterfaceTypeFirewireValue) { interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire; }done: if (ioInterfaceNamePrefix != NULL) { CFRelease(ioInterfaceNamePrefix); }
return (SCNetworkInterfaceRef)interfacePrivate;}
__private_extern__void_SCNetworkInterfaceCacheOpen(void){ if (!__SCNetworkInterfaceCacheIsOpen()) { S_interface_cache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): open", S_interface_cache); }}
__private_extern__void_SCNetworkInterfaceCacheClose(void){ if (__SCNetworkInterfaceCacheIsOpen()) { SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): close", S_interface_cache); CFRelease(S_interface_cache); S_interface_cache = NULL; }}
static void__SCNetworkInterfaceCacheAdd(CFStringRef bsdName, CFArrayRef matchingInterfaces){ if (__SCNetworkInterfaceCacheIsOpen() && bsdName != NULL && matchingInterfaces != NULL) { SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): add %@", S_interface_cache, bsdName); CFDictionaryAddValue(S_interface_cache, bsdName, matchingInterfaces); }}
static inline Boolean__SCNetworkInterfaceCacheIsOpen(void){ return (S_interface_cache != NULL);}
static CFArrayRef__SCNetworkInterfaceCacheCopy(CFStringRef bsdName){ if (__SCNetworkInterfaceCacheIsOpen() && bsdName != NULL) { CFArrayRef matchingInterfaces = CFDictionaryGetValue(S_interface_cache, bsdName); if (matchingInterfaces) { CFRetain(matchingInterfaces); SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): copy w/ match for %@", S_interface_cache, bsdName); } else { SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): copy w/ no match for %@", S_interface_cache, bsdName); }
return matchingInterfaces; }
return NULL;}
SCNetworkInterfaceRef_SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, CFDictionaryRef interface_entity, SCNetworkServiceRef service){#pragma unused(allocator) SCNetworkInterfacePrivateRef interfacePrivate = NULL; CFStringRef ifDevice; CFStringRef ifName = NULL; CFStringRef ifSubType; CFStringRef ifType; CFStringRef ifUnique; CFArrayRef matching_interfaces = NULL; SCPreferencesRef servicePref = NULL; Boolean useSystemInterfaces = TRUE;
/* initialize runtime (and kSCNetworkInterfaceIPv4) */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (service != NULL) { servicePref = ((SCNetworkServicePrivateRef)service)->prefs; useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePref)) && (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref))); }
ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType); if (ifType == NULL) { /* * The interface "Type" was not specified. We'll make an * assumption that this is an "Ethernet" interface. If a * real interface exists with the provided interface name * then the actual type will be set accordingly. If not, we'll * end up crafting an "Ethernet" SCNetworkInterface that * will keep the rest of the configuration APIs happy. */ ifType = kSCValNetInterfaceTypeEthernet; }
if (!isA_CFString(ifType)) { return NULL; }
ifSubType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceSubType); if (CFEqual(ifType, kSCValNetInterfaceTypePPP) || CFEqual(ifType, kSCValNetInterfaceTypeVPN)) { if (!isA_CFString(ifSubType)) { return NULL; } }
ifDevice = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceDeviceName); ifUnique = CFDictionaryGetValue(interface_entity, CFSTR("DeviceUniqueIdentifier"));
if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet) || CFEqual(ifType, kSCValNetInterfaceTypeFireWire) || (CFEqual(ifType, kSCValNetInterfaceTypePPP) && CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE))) { char bsdName[IFNAMSIZ]; CFMutableDictionaryRef matching;
if (!isA_CFString(ifDevice)) { return NULL; }
if (CFEqual(ifDevice, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName interfacePrivate = __SCNetworkInterfaceCreateCopy(NULL, kSCNetworkInterfaceLoopback, NULL, NULL); goto done; } if (useSystemInterfaces) { // Check to see if we already have the info in the cache matching_interfaces = __SCNetworkInterfaceCacheCopy(ifDevice); if (matching_interfaces == NULL) { if (_SC_cfstring_to_cstring(ifDevice, bsdName, sizeof(bsdName), kCFStringEncodingASCII) == NULL) { goto done; }
matching = IOBSDNameMatching(masterPort, 0, bsdName); if (matching == NULL) { goto done; } matching_interfaces = findMatchingInterfaces(matching, processNetworkInterface, kSCNetworkInterfaceHiddenInterfaceKey, TRUE);
__SCNetworkInterfaceCacheAdd(ifDevice, matching_interfaces); CFRelease(matching); } } } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) { if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPSerial)) { CFDictionaryRef matching; CFStringRef match_keys[2]; CFStringRef match_vals[2];
if (!isA_CFString(ifDevice)) { return NULL; }
if (useSystemInterfaces) { match_keys[0] = CFSTR(kIOProviderClassKey); match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
match_keys[1] = CFSTR(kIOTTYBaseNameKey); match_vals[1] = ifDevice;
matching = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); matching_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey, TRUE); CFRelease(matching); } if (ifUnique == NULL) { CFIndex n; Boolean useDeviceName = TRUE;
n = (matching_interfaces != NULL) ? CFArrayGetCount(matching_interfaces) : 0; if (n > 0) { CFIndex i;
for (i = 0; i < n; i++) { SCNetworkInterfacePrivateRef scanPrivate;
scanPrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, i); if (scanPrivate->entity_device_unique != NULL) { useDeviceName = FALSE; break; } } }
if (useDeviceName && useSystemInterfaces) { if (matching_interfaces != NULL) { CFRelease(matching_interfaces); }
match_keys[1] = CFSTR(kIOTTYDeviceKey); matching = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); matching_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey, TRUE); CFRelease(matching); } } } else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypeL2TP)) { interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceTypeL2TP);#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wdeprecated" } else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPTP)) { interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceTypePPTP);#pragma GCC diagnostic pop } else { // XXX do we allow non-Apple variants of PPP??? XXX interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType); } } else if (CFEqual(ifType, kSCValNetInterfaceType6to4)) { if (!isA_CFString(ifDevice)) { return NULL; }
interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceType6to4); } else if (CFEqual(ifType, kSCValNetInterfaceTypeIPSec)) { interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceTypeIPSec); } else if (CFEqual(ifType, kSCValNetInterfaceTypeLoopback)) { interfacePrivate = __SCNetworkInterfaceCreateCopy(NULL, kSCNetworkInterfaceLoopback, NULL, NULL); } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN)) { if (CFStringFind(ifSubType, CFSTR("."), 0).location != kCFNotFound) { interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType); } } else if ((CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) && (ifDevice == NULL)) { interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifType); }
if (matching_interfaces != NULL) { CFIndex n; SCPreferencesRef prefs; Boolean temp_preferences = FALSE;
n = CFArrayGetCount(matching_interfaces); switch (n) { case 1 : interfacePrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, 0); if (_SC_CFEqual(ifUnique, interfacePrivate->entity_device_unique)) { // if the unique ID's match CFRetain(interfacePrivate); break; }
interfacePrivate = NULL; // fall through case 0 : if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) { break; }
if (CFDictionaryGetValueIfPresent(interface_entity, kSCPropUserDefinedName, (const void **)&ifName) && CFEqual(ifName, CFSTR(BT_PAN_NAME))) { break; }
prefs = (service != NULL) ? ((SCNetworkServicePrivateRef)service)->prefs : NULL; if (prefs == NULL) { prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL); if (prefs != NULL) { temp_preferences = TRUE; } } if (prefs == NULL) { break; }#if !TARGET_OS_IPHONE if (!CFDictionaryContainsKey(interface_entity, CFSTR("_NO_BOND_INTERFACES_"))) { interfacePrivate = (SCNetworkInterfacePrivateRef)findBondInterface(prefs, ifDevice); }#endif // !TARGET_OS_IPHONE if ((interfacePrivate == NULL) && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_BRIDGE_INTERFACES_"))) { interfacePrivate = (SCNetworkInterfacePrivateRef)findBridgeInterface(prefs, ifDevice); }
if ((interfacePrivate == NULL) && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) { interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice); } if (temp_preferences) CFRelease(prefs); break; default : if (ifUnique != NULL) { CFIndex i;
// we are looking for an interface with a unique ID // so let's try to focus our choices for (i = 0; i < n; i++) { SCNetworkInterfacePrivateRef scanPrivate;
scanPrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, i); if (_SC_CFEqual(ifUnique, scanPrivate->entity_device_unique)) { if (interfacePrivate != NULL) { // if we've matched more than one interface interfacePrivate = NULL; break; } interfacePrivate = scanPrivate; } } } else if (CFDictionaryGetValueIfPresent(interface_entity, kSCPropUserDefinedName, (const void **)&ifName)) { CFIndex i;
// we don't have a unique ID but do have an interface // name. If the matching interfaces do have IDs than // we can try to focus our choices using the name for (i = 0; i < n; i++) { SCNetworkInterfacePrivateRef scanPrivate;
scanPrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, i); if (scanPrivate->entity_device_unique != NULL) { SCNetworkInterfaceRef scan = (SCNetworkInterfaceRef)scanPrivate; CFStringRef scanName;
scanName = __SCNetworkInterfaceGetNonLocalizedDisplayName(scan); if ((scanName != NULL) && !_SC_CFEqual(ifName, scanName)) { continue; // if not the same display name } }
if (interfacePrivate != NULL) { // if we've matched more than one interface interfacePrivate = NULL; break; } interfacePrivate = scanPrivate; } } if (interfacePrivate == NULL) { SC_log(LOG_NOTICE, "more than one interface matches %@", ifDevice); interfacePrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, 0); } CFRetain(interfacePrivate); break; } CFRelease(matching_interfaces); }
done :
if ((interfacePrivate == NULL) || !useSystemInterfaces) { /* * if device not present on this system */ if (!useSystemInterfaces) { if (interfacePrivate != NULL) { CFRelease(interfacePrivate); } }
interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL); interfacePrivate->entity_type = (ifType != NULL) ? ifType : NULL; interfacePrivate->entity_subtype = (ifSubType != NULL) ? ifSubType : NULL; interfacePrivate->entity_device = (ifDevice != NULL) ? CFStringCreateCopy(NULL, ifDevice) : NULL; interfacePrivate->entity_device_unique = (ifUnique != NULL) ? CFStringCreateCopy(NULL, ifUnique) : NULL;
// Using UserDefinedName to check the validity of preferences file // when useSystemInterfaces is FALSE if (!useSystemInterfaces) { CFStringRef userDefinedName = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName); if (isA_CFString(userDefinedName) != NULL) { CFRetain(userDefinedName); if (interfacePrivate->name != NULL) { CFRelease(interfacePrivate->name); } interfacePrivate->name = userDefinedName;
CFRetain(userDefinedName); if (interfacePrivate->localized_name != NULL) { CFRelease(interfacePrivate->localized_name); } interfacePrivate->localized_name = userDefinedName; } }
if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) { CFStringRef entity_hardware; SCNetworkInterfaceRef virtualInterface;
if (!useSystemInterfaces && (((virtualInterface = findBridgeInterface(servicePref, ifDevice)) != NULL) ||#if !TARGET_OS_IPHONE ((virtualInterface = findBondInterface(servicePref, ifDevice)) != NULL) ||#endif // !TARGET_OS_IPHONE ((virtualInterface = findVLANInterface(servicePref, ifDevice)) != NULL))) { CFRelease(interfacePrivate); interfacePrivate = (SCNetworkInterfacePrivateRef)virtualInterface; } else { entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware); if (isA_CFString((entity_hardware)) && CFEqual(entity_hardware, kSCEntNetAirPort)) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211; interfacePrivate->localized_key = CFSTR("airport"); interfacePrivate->sort_order = kSortAirPort; } else { CFStringRef name;
interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
name = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName); if (__SCNetworkInterfaceMatchesName(name, CFSTR("iPhone"))) { interfacePrivate->localized_key = CFSTR("iPhone"); interfacePrivate->sort_order = kSortTethered; } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("iPad"))) { interfacePrivate->localized_key = CFSTR("iPad"); interfacePrivate->sort_order = kSortTethered; } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("thunderbolt"))) { interfacePrivate->localized_key = CFSTR("thunderbolt"); interfacePrivate->sort_order = kSortThunderbolt; } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-gn"))) { interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn"); interfacePrivate->sort_order = kSortBluetoothPAN_GN; } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-nap"))) { interfacePrivate->localized_key = CFSTR("bluetooth-pan-nap"); interfacePrivate->sort_order = kSortBluetoothPAN_NAP; } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-u"))) { interfacePrivate->localized_key = CFSTR("bluetooth-pan-u"); interfacePrivate->sort_order = kSortBluetoothPAN_U; } else { interfacePrivate->sort_order = kSortEthernet; } } } } else if (CFEqual(ifType, kSCValNetInterfaceTypeFireWire)) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeFireWire; interfacePrivate->sort_order = kSortFireWire; } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP) && (ifSubType != NULL)) { if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE)) { CFStringRef entity_hardware;
entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware); if (isA_CFString((entity_hardware)) && CFEqual(entity_hardware, kSCEntNetAirPort)) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211; interfacePrivate->sort_order = kSortAirPort; } else { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->sort_order = kSortEthernet; } } else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPSerial)) { if (CFStringHasPrefix(ifDevice, CFSTR("Bluetooth"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeBluetooth; interfacePrivate->sort_order = kSortBluetooth; } else if (CFStringHasPrefix(ifDevice, CFSTR("irda"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeIrDA; interfacePrivate->sort_order = kSortIrDA; } else if (CFStringHasPrefix(ifDevice, CFSTR("wwan"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeWWAN; interfacePrivate->sort_order = kSortWWAN; } else { interfacePrivate->interface_type = kSCNetworkInterfaceTypeModem; interfacePrivate->sort_order = kSortModem; } } else { SCNetworkInterfaceRef child; // PPTP, L2TP, ... CFRelease(interfacePrivate); child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType); interfacePrivate = (SCNetworkInterfacePrivateRef)child; if (interfacePrivate == NULL) { return NULL; } } } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN) && (ifSubType != NULL)) { SCNetworkInterfaceRef child; CFRelease(interfacePrivate); child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType); interfacePrivate = (SCNetworkInterfacePrivateRef)child; if (interfacePrivate == NULL) { return NULL; } } else if (CFEqual(ifType, kSCValNetInterfaceTypeIPSec)) { CFRelease(interfacePrivate); interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceTypeIPSec); } else if (CFEqual(ifType, kSCValNetInterfaceType6to4)) { CFRelease(interfacePrivate); if (!isA_CFString(ifDevice)) { return NULL; } interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceType6to4); } else if (CFEqual(ifType, kSCValNetInterfaceTypeLoopback)) { CFRelease(interfacePrivate); interfacePrivate = __SCNetworkInterfaceCreateCopy(NULL, kSCNetworkInterfaceLoopback, NULL, NULL); } else if (CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) { // if vendor interface pthread_mutex_lock(&lock); if (vendor_interface_types == NULL) { vendor_interface_types = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); } CFSetAddValue(vendor_interface_types, ifType); interfacePrivate->interface_type = CFSetGetValue(vendor_interface_types, ifType); pthread_mutex_unlock(&lock); } else { // if unknown interface CFRelease(interfacePrivate); interfacePrivate = NULL; return NULL; }
if (CFDictionaryContainsKey(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey)) { interfacePrivate->hidden = TRUE; }#if TARGET_OS_IPHONE if (CFDictionaryContainsKey(interface_entity, kSCNetworkInterfaceTrustRequiredKey)) { interfacePrivate->trustRequired = TRUE; }#endif // TARGET_OS_IPHONE }
if (service != NULL) { __SCNetworkInterfaceSetService((SCNetworkInterfaceRef)interfacePrivate, service);
#if !TARGET_OS_IPHONE // set prefs & serviceID to Bond member interfaces if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeBond)) { CFIndex i; CFArrayRef members; CFIndex n;
members = SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef)interfacePrivate); n = (members != NULL) ? CFArrayGetCount(members) : 0; for (i = 0; i < n; i++) { SCNetworkInterfaceRef member;
member = CFArrayGetValueAtIndex(members, i); __SCNetworkInterfaceSetService(member, service); } }#endif // !TARGET_OS_IPHONE
// set prefs & serviceID to Bridge member interfaces if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeBridge)) { CFIndex i; CFArrayRef members; CFIndex n;
members = SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef)interfacePrivate); n = (members != NULL) ? CFArrayGetCount(members) : 0; for (i = 0; i < n; i++) { SCNetworkInterfaceRef member;
member = CFArrayGetValueAtIndex(members, i); __SCNetworkInterfaceSetService(member, service); } } // set prefs & serviceID to VLAN pyhsical interface if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeVLAN)) { SCNetworkInterfaceRef vlan_physical;
vlan_physical = SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef)interfacePrivate); if (vlan_physical != NULL) { __SCNetworkInterfaceSetService(vlan_physical, service); } } }
if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) { SCNetworkInterfaceRef parent;
// create parent parent = SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef)interfacePrivate, kSCNetworkInterfaceTypePPP); CFRelease(interfacePrivate); interfacePrivate = (SCNetworkInterfacePrivateRef)parent; } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN)) { SCNetworkInterfaceRef parent;
// create parent parent = SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef)interfacePrivate, kSCNetworkInterfaceTypeVPN); CFRelease(interfacePrivate); interfacePrivate = (SCNetworkInterfacePrivateRef)parent; }
return (SCNetworkInterfaceRef)interfacePrivate;}
#pragma mark -#pragma mark SCNetworkInterface APIs
__private_extern__CFArrayRef__SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured){ CFDictionaryRef matching; CFArrayRef new_interfaces;
// get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
matching = IOServiceMatching(kIONetworkInterfaceClass); new_interfaces = findMatchingInterfaces(matching, processNetworkInterface, kSCNetworkInterfaceHiddenInterfaceKey, keep_pre_configured); CFRelease(matching);
return new_interfaces;}
staticCFArrayRef__SCNetworkInterfaceCopyAll_Modem(){ CFDictionaryRef matching; CFStringRef match_keys[2]; CFStringRef match_vals[2]; CFArrayRef new_interfaces;
match_keys[0] = CFSTR(kIOProviderClassKey); match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
match_keys[1] = CFSTR(kIOSerialBSDTypeKey); match_vals[1] = CFSTR(kIOSerialBSDModemType);
matching = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); new_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey, FALSE); CFRelease(matching);
return new_interfaces;}
staticCFArrayRef__SCNetworkInterfaceCopyAll_RS232(){ CFDictionaryRef matching; CFStringRef match_keys[2]; CFStringRef match_vals[2]; CFArrayRef new_interfaces;
match_keys[0] = CFSTR(kIOProviderClassKey); match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
match_keys[1] = CFSTR(kIOSerialBSDTypeKey); match_vals[1] = CFSTR(kIOSerialBSDRS232Type);
matching = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); new_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey, FALSE); CFRelease(matching);
return new_interfaces;}
#if !TARGET_OS_IPHONEstatic voidaddBTPANInterface(CFMutableArrayRef all_interfaces){ CFIndex i; SCNetworkInterfaceRef interface; CFIndex n;
n = CFArrayGetCount(all_interfaces); for (i = 0; i < n; i++) { SCNetworkInterfaceRef interface;
interface = CFArrayGetValueAtIndex(all_interfaces, i); if (_SCNetworkInterfaceIsBluetoothPAN(interface)) { // if we already have a BT-PAN interface return; } }
interface = _SCNetworkInterfaceCopyBTPANInterface(); if (interface != NULL) { // include BT-PAN interface CFArrayAppendValue(all_interfaces, interface); CFRelease(interface); }
return;}#endif // !TARGET_OS_IPHONE
static voidadd_interfaces(CFMutableArrayRef all_interfaces, CFArrayRef new_interfaces){ CFIndex i; CFIndex n;
n = CFArrayGetCount(new_interfaces); for (i = 0; i < n; i++) { CFStringRef bsdName; SCNetworkInterfaceRef interface;
interface = CFArrayGetValueAtIndex(new_interfaces, i); bsdName = SCNetworkInterfaceGetBSDName(interface); if (bsdName != NULL) { CFArrayAppendValue(all_interfaces, interface); } }
return;}
static void__waitForInterfaces(){ CFStringRef key = NULL; CFArrayRef keys; Boolean ok; SCDynamicStoreRef store = NULL;
CRSetCrashLogMessage("Waiting for IOKit to quiesce (or timeout)");
store = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkInterfaceCopyAll"), NULL, NULL); if (store == NULL) { goto done; }
key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin); keys = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks); ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL); CFRelease(keys); if (!ok) { SC_log(LOG_NOTICE, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError())); goto done; }
while (TRUE) { CFArrayRef changedKeys; CFDictionaryRef dict; Boolean quiet = FALSE;
// check if quiet dict = SCDynamicStoreCopyValue(store, key); if (dict != NULL) { if (isA_CFDictionary(dict) && (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet) || CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout))) { quiet = TRUE; } CFRelease(dict); } if (quiet) { break; }
ok = SCDynamicStoreNotifyWait(store); if (!ok) { SC_log(LOG_NOTICE, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError())); goto done; }
changedKeys = SCDynamicStoreCopyNotifiedKeys(store); if (changedKeys != NULL) { CFRelease(changedKeys); } }
done :
CRSetCrashLogMessage(NULL);
if (key != NULL) CFRelease(key); if (store != NULL) CFRelease(store); return;}
CFArrayRef /* of SCNetworkInterfaceRef's */_SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs){ CFMutableArrayRef all_interfaces; CFArrayRef new_interfaces; Boolean temp_preferences = FALSE;
/* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
/* wait for IOKit to quiesce */ pthread_once(&iokit_quiet, __waitForInterfaces);
all_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
// get Ethernet, Firewire, Thunderbolt, and AirPort interfaces new_interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE); if (new_interfaces != NULL) { add_interfaces(all_interfaces, new_interfaces); CFRelease(new_interfaces); }
// get Modem interfaces new_interfaces = __SCNetworkInterfaceCopyAll_Modem(); if (new_interfaces != NULL) { add_interfaces(all_interfaces, new_interfaces); CFRelease(new_interfaces); }
// get serial (RS232) interfaces new_interfaces = __SCNetworkInterfaceCopyAll_RS232(); if (new_interfaces != NULL) { add_interfaces(all_interfaces, new_interfaces); CFRelease(new_interfaces); }
// get virtual network interfaces (Bond, Bridge, VLAN) if (prefs == NULL) { prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterfaceCopyAll"), NULL); if (prefs != NULL) { temp_preferences = TRUE; } } if (prefs != NULL) {#if !TARGET_OS_IPHONE new_interfaces = SCBondInterfaceCopyAll(prefs); if (new_interfaces != NULL) { add_interfaces(all_interfaces, new_interfaces); CFRelease(new_interfaces); }#endif // !TARGET_OS_IPHONE
new_interfaces = SCBridgeInterfaceCopyAll(prefs); if (new_interfaces != NULL) { add_interfaces(all_interfaces, new_interfaces); CFRelease(new_interfaces); }
new_interfaces = SCVLANInterfaceCopyAll(prefs); if (new_interfaces != NULL) { add_interfaces(all_interfaces, new_interfaces); CFRelease(new_interfaces); }
#if !TARGET_OS_IPHONE // add BT-PAN interface addBTPANInterface(all_interfaces);#endif // !TARGET_OS_IPHONE
if (temp_preferences) CFRelease(prefs); }
// all interfaces have been identified, order and return sort_interfaces(all_interfaces);
return all_interfaces;}
CFArrayRef /* of SCNetworkInterfaceRef's */SCNetworkInterfaceCopyAll(){ CFArrayRef all_interfaces;
all_interfaces = _SCNetworkInterfaceCopyAllWithPreferences(NULL); return all_interfaces;}
CFArrayRef /* of kSCNetworkInterfaceTypeXXX CFStringRef's */SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface){ CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (interfacePrivate->supported_interface_types != NULL) { goto done; }
i = findConfiguration(interfacePrivate->interface_type); if (i != kCFNotFound) { if (configurations[i].supported_interfaces != doNone) { interfacePrivate->supported_interface_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); if (configurations[i].supported_interfaces & do6to4) { CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceType6to4); } if (configurations[i].supported_interfaces & doL2TP) { CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeL2TP); } if (configurations[i].supported_interfaces & doPPP) { CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPP); } if (configurations[i].supported_interfaces & doIPSec) { CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeIPSec); } } } else { SCNetworkInterfaceRef child;
child = SCNetworkInterfaceGetInterface(interface); if ((child != NULL) && CFEqual(child, kSCNetworkInterfaceIPv4)) { interfacePrivate->supported_interface_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeVPN); } }
done :
return interfacePrivate->supported_interface_types;}
CFArrayRef /* of kSCNetworkProtocolTypeXXX CFStringRef's */SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface){ CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (interfacePrivate->supported_protocol_types != NULL) { goto done; }
i = findConfiguration(interfacePrivate->interface_type); if (i != kCFNotFound) { if (configurations[i].supported_protocols != doNone) { interfacePrivate->supported_protocol_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); if (configurations[i].supported_protocols & doDNS) { CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeDNS); } if (configurations[i].supported_protocols & doIPv4) { CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeIPv4); } if (configurations[i].supported_protocols & doIPv6) { CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeIPv6); } if (configurations[i].supported_protocols & doProxies) { CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeProxies); }#if !TARGET_OS_IPHONE if (configurations[i].supported_protocols & doSMB) { CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeSMB); }#endif // !TARGET_OS_IPHONE } }
done :
return interfacePrivate->supported_protocol_types;}
SCNetworkInterfaceRefSCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef interfaceType){ SCNetworkInterfacePrivateRef childPrivate = (SCNetworkInterfacePrivateRef)child; CFIndex childIndex; SCNetworkInterfacePrivateRef parentPrivate;
if (!isA_SCNetworkInterface(child)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (!isA_CFString(interfaceType)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (CFEqual(child, kSCNetworkInterfaceLoopback)) { // can't layer on top of loopback _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
childIndex = findConfiguration(childPrivate->interface_type);
parentPrivate = __SCNetworkInterfaceCreatePrivate(NULL, child, childPrivate->prefs, childPrivate->serviceID); if (parentPrivate == NULL) { _SCErrorSet(kSCStatusFailed); return NULL; }
if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) { parentPrivate->interface_type = kSCNetworkInterfaceTypePPP; parentPrivate->entity_type = kSCValNetInterfaceTypePPP;
// entity subtype if (childIndex != kCFNotFound) { if (configurations[childIndex].ppp_subtype != NULL) { parentPrivate->entity_subtype = *configurations[childIndex].ppp_subtype; } else { // sorry, the child interface does not support PPP goto fail; } } else { // if the child's interface type not known, use the child entities "Type" parentPrivate->entity_subtype = childPrivate->entity_type; }
if (childPrivate->entity_device != NULL) { parentPrivate->entity_device = CFStringCreateCopy(NULL, childPrivate->entity_device); }
if (childPrivate->entity_device_unique != NULL) { parentPrivate->entity_device_unique = CFStringCreateCopy(NULL, childPrivate->entity_device_unique); } } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) { if ((childIndex == kCFNotFound) || ((configurations[childIndex].supported_interfaces & doL2TP) != doL2TP)) { // if the child interface does not support L2TP goto fail; } parentPrivate->interface_type = kSCNetworkInterfaceTypeL2TP; parentPrivate->localized_key = CFSTR("l2tp"); parentPrivate->entity_type = kSCEntNetL2TP; // interface config goes into "L2TP"#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wdeprecated" } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPTP)) { if ((childIndex == kCFNotFound) || ((configurations[childIndex].supported_interfaces & doPPTP) != doPPTP)) { // if the child interface does not support PPTP goto fail; } parentPrivate->interface_type = kSCNetworkInterfaceTypePPTP; parentPrivate->localized_key = CFSTR("pptp"); parentPrivate->entity_type = kSCEntNetPPTP; // interface config goes into "PPTP"#pragma GCC diagnostic pop } else if (CFEqual(interfaceType, kSCNetworkInterfaceType6to4)) { if ((childIndex == kCFNotFound) || ((configurations[childIndex].supported_interfaces & do6to4) != do6to4)) { // if the child interface does not support 6to4 goto fail; }
parentPrivate->interface_type = kSCNetworkInterfaceType6to4; parentPrivate->localized_key = CFSTR("6to4"); parentPrivate->entity_type = kSCValNetInterfaceType6to4; parentPrivate->entity_device = CFRetain(CFSTR("stf0")); } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) { if ((childIndex == kCFNotFound) || ((configurations[childIndex].supported_interfaces & doIPSec) != doIPSec)) { // if the child interface does not support IPSec goto fail; } parentPrivate->interface_type = kSCNetworkInterfaceTypeIPSec; parentPrivate->localized_key = CFSTR("ipsec"); parentPrivate->entity_type = kSCValNetInterfaceTypeIPSec; } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) { if (childIndex != kCFNotFound) { // if not a "vendor" child interface goto fail; }
parentPrivate->interface_type = kSCNetworkInterfaceTypeVPN; parentPrivate->localized_key = CFSTR("vpn"); parentPrivate->localized_arg1 = CFRetain(childPrivate->entity_type); parentPrivate->entity_type = kSCValNetInterfaceTypeVPN; parentPrivate->entity_subtype = childPrivate->entity_type; if (childPrivate->entity_device != NULL) { parentPrivate->entity_device = CFStringCreateCopy(NULL, childPrivate->entity_device); } if (parentPrivate->entity_subtype != NULL) { CFArrayRef components; CFIndex n; CFStringRef vpnType;
// // the "default" interface name is derived from the VPN type // // e.g. // com.apple.Apple-VPN.vpnplugin --> "Apple VPN" // ^^^^^^^^^ // vpnType = parentPrivate->entity_subtype; components = CFStringCreateArrayBySeparatingStrings(NULL, vpnType, CFSTR(".")); n = CFArrayGetCount(components); if ((n >= 4) && CFEqual(CFArrayGetValueAtIndex(components, n - 1), CFSTR("vpnplugin"))) { CFMutableStringRef str;
str = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(components, n - 2)); (void) CFStringFindAndReplace(str, CFSTR("-"), CFSTR(" "), CFRangeMake(0, CFStringGetLength(str)), 0); parentPrivate->localized_name = str; } CFRelease(components); } } else if (CFStringFind(interfaceType, CFSTR("."), 0).location != kCFNotFound) { // if custom interface type pthread_mutex_lock(&lock); if (vendor_interface_types == NULL) { vendor_interface_types = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); } CFSetAddValue(vendor_interface_types, interfaceType); parentPrivate->interface_type = CFSetGetValue(vendor_interface_types, interfaceType); pthread_mutex_unlock(&lock);
parentPrivate->entity_type = parentPrivate->interface_type; // interface config goes into a // a dictionary with the same // name as the interfaceType } else { // unknown interface type goto fail; }
parentPrivate->hidden = childPrivate->hidden;
#if TARGET_OS_IPHONE parentPrivate->trustRequired = childPrivate->trustRequired;#endif // TARGET_OS_IPHONE
if (childPrivate->overrides != NULL) { parentPrivate->overrides = CFDictionaryCreateMutableCopy(NULL, 0, childPrivate->overrides); }
// The following change handles the case where a user has both an Ethernet and // PPPoE network service. Because a PPPoE service is typically associated with // an ISP we want it to be sorted higher in the service order. if ((parentPrivate->entity_subtype != NULL) && (CFEqual(parentPrivate->entity_subtype, kSCValNetInterfaceSubTypePPPoE))) { if ((childPrivate->interface_type != NULL) && (CFEqual(childPrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211))) { parentPrivate->sort_order = kSortAirportPPP; } else { parentPrivate->sort_order = kSortEthernetPPP; } } else { // set sort order of the parent to match the child interface parentPrivate->sort_order = childPrivate->sort_order; }
return (SCNetworkInterfaceRef)parentPrivate;
fail :
CFRelease(parentPrivate); _SCErrorSet(kSCStatusInvalidArgument); return NULL;}
__private_extern__CFDictionaryRef__SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface){ CFDictionaryRef config = NULL; CFStringRef defaultType; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
/* initialize runtime (and kSCNetworkInterfaceIPv4) */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType != NULL) { if (set != NULL) { CFStringRef path;
path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL, // allocator SCNetworkSetGetSetID(set), // set interfacePrivate->entity_device, // interface defaultType); // entity if (path != NULL) { config = __getPrefsConfiguration(interfacePrivate->prefs, path); CFRelease(path);
if (config == NULL) { // if the "set" does not have a saved configuration, use // the [template] "interface" configuration if (interfacePrivate->unsaved != NULL) { config = CFDictionaryGetValue(interfacePrivate->unsaved, defaultType); if (config == (CFDictionaryRef)kCFNull) { config = NULL; } } } if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) { config = NULL; } } } }
return config;}
static CFDictionaryRef__SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface, CFStringRef extendedType){ CFDictionaryRef config = NULL; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFArrayRef paths;
/* initialize runtime (and kSCNetworkInterfaceIPv4) */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
paths = copyConfigurationPaths(interfacePrivate, extendedType); if (paths != NULL) { CFStringRef path;
path = CFArrayGetValueAtIndex(paths, 0); config = __getPrefsConfiguration(interfacePrivate->prefs, path);
CFRelease(paths); } else { if (interfacePrivate->unsaved != NULL) { config = CFDictionaryGetValue(interfacePrivate->unsaved, extendedType); if (config == (CFDictionaryRef)kCFNull) { config = NULL; } } }
if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) { config = NULL; }
return config;}
CFDictionaryRefSCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface){ CFDictionaryRef config; CFStringRef defaultType;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType == NULL) { return NULL; }
config = __SCNetworkInterfaceGetConfiguration(interface, defaultType); if (config == NULL) { if (CFEqual(defaultType, kSCEntNetAirPort)) { SCNetworkInterfacePrivateRef interfacePrivate; CFStringRef path;
// if AirPort interface, check for a per-service config interfacePrivate = (SCNetworkInterfacePrivateRef)interface; path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator interfacePrivate->serviceID, // service kSCEntNetAirPort); // entity config = __getPrefsConfiguration(interfacePrivate->prefs, path); CFRelease(path); } } if (config == NULL) { _SCErrorSet(kSCStatusOK); }
return config;}
CFDictionaryRefSCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface, CFStringRef extendedType){ CFDictionaryRef config;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, TRUE)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
config = __SCNetworkInterfaceGetConfiguration(interface, extendedType); if (config == NULL) { _SCErrorSet(kSCStatusOK); }
return config;}
__private_extern__CFStringRef__SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->entity_type;}
__private_extern__CFStringRef__SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
return interfacePrivate->entity_subtype;}
CFStringRefSCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if ((interfacePrivate->interface != NULL) && (interfacePrivate->interface != kSCNetworkInterfaceIPv4)) { _SCErrorSet(kSCStatusOK); return NULL; }
return interfacePrivate->entity_device;}
CFStringRefSCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if ((interfacePrivate->address != NULL) && (interfacePrivate->addressString == NULL)) { uint8_t *bp; char *cp; size_t n; char mac[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")]; char *mac_p = mac;
bp = (uint8_t *)CFDataGetBytePtr(interfacePrivate->address); n = CFDataGetLength(interfacePrivate->address) * 3;
if (n > sizeof(mac)) { mac_p = CFAllocatorAllocate(NULL, n, 0); }
for (cp = mac_p; n > 0; n -= 3) { cp += snprintf(cp, n, "%2.2x:", *bp++); }
interfacePrivate->addressString = CFStringCreateWithCString(NULL, mac_p, kCFStringEncodingUTF8); if (mac_p != mac) CFAllocatorDeallocate(NULL, mac_p); }
return interfacePrivate->addressString;}
SCNetworkInterfaceRefSCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
return interfacePrivate->interface;}
CFStringRefSCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
return interfacePrivate->interface_type;}
static CFStringRefcopy_string_from_bundle(CFBundleRef bundle, CFStringRef key, Boolean localized){ CFStringRef str = NULL;
if (localized) { str = CFBundleCopyLocalizedString(bundle, key, key, NETWORKINTERFACE_LOCALIZATIONS); } else { str = _SC_CFBundleCopyNonLocalizedString(bundle, key, key, NETWORKINTERFACE_LOCALIZATIONS); }
return str;}
static CFStringRefcopy_interface_string(CFBundleRef bundle, CFStringRef key, Boolean localized){ static Boolean reported = FALSE; CFStringRef str = NULL;
str = copy_string_from_bundle(bundle, key, localized);
if (str == NULL) { SC_log(LOG_ERR, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle, key, localized); goto done; }
if (CFEqual(str, key) && !reported) { const CFStringRef knownStrKey = CFSTR("airport"); CFStringRef knownStrValue = NULL;
knownStrValue = copy_string_from_bundle(bundle, knownStrKey, localized); if (knownStrValue == NULL || CFEqual(knownStrValue, knownStrKey)) { /* We are here because we requested for a localized/non-localized string based on the localization key, but we were given the same key/NULL back, implying a bad...bad thing! */ SC_log(LOG_ERR, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle, knownStrKey, localized);
#if TARGET_OS_IPHONE /* ...and we want to know about it! */ _SC_crash("Failed to retrieve interface string", NULL, NULL);#endif //TARGET_OS_IPHONE reported = TRUE; }
if (knownStrValue != NULL) { CFRelease(knownStrValue); } }
done: return str;}
static CFStringRefcopy_display_name(SCNetworkInterfaceRef interface, Boolean localized, Boolean oldLocalization){ CFMutableStringRef local; CFStringRef name;
local = CFStringCreateMutable(NULL, 0);
while (interface != NULL) { Boolean added = FALSE; SCNetworkInterfaceRef child = NULL; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if ((interfacePrivate->interface != NULL) && (interfacePrivate->interface != kSCNetworkInterfaceIPv4) && !CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeVPN)) { child = interfacePrivate->interface; }
if ((bundle != NULL) && (interfacePrivate->localized_key != NULL)) { CFStringRef fmt; CFStringRef key = interfacePrivate->localized_key;
if (oldLocalization) { key = CFStringCreateWithFormat(NULL, NULL, CFSTR("X-%@"), interfacePrivate->localized_key); } fmt = copy_interface_string(bundle, key, localized); if (fmt != NULL) { CFStringAppendFormat(local, NULL, fmt, interfacePrivate->localized_arg1, interfacePrivate->localized_arg2); CFRelease(fmt); added = TRUE; } if (oldLocalization) { CFRelease(key); } }
if (!added && (interfacePrivate->prefs != NULL) && (interfacePrivate->serviceID != NULL) && (child == NULL)) { CFDictionaryRef entity; CFStringRef path;
// check for (and use) the name of the interface when it // was last available path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, interfacePrivate->serviceID, kSCEntNetInterface); entity = SCPreferencesPathGetValue(interfacePrivate->prefs, path); CFRelease(path); if (isA_CFDictionary(entity)) { CFStringRef name;
name = CFDictionaryGetValue(entity, kSCPropUserDefinedName); if (isA_CFString(name)) { CFStringAppend(local, name); added = TRUE; } } }
if (!added) { // create (non-)localized name based on the interface type CFStringAppend(local, interfacePrivate->interface_type);
// ... and, if this is a leaf node, the interface device if ((interfacePrivate->entity_device != NULL) && (child == NULL)) { CFStringAppendFormat(local, NULL, CFSTR(" (%@)"), interfacePrivate->entity_device); } }
if (child != NULL) { // if this interface is layered over another CFStringAppend(local, CFSTR(" --> ")); }
interface = child; }
name = CFStringCreateCopy(NULL, local); CFRelease(local);
return name;}
#if !TARGET_OS_IPHONE__private_extern__CFStringRef__SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface){ CFStringRef name;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
name = copy_display_name(interface, TRUE, TRUE); return name;}
__private_extern__CFStringRef__SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface){ CFStringRef localized_name;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
localized_name = copy_display_name(interface, FALSE, TRUE); return localized_name;}#endif // !TARGET_OS_IPHONE
__private_extern__void__SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface, CFStringRef name){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { return; } if (name != NULL) { CFRetain(name); } if (interfacePrivate->name != NULL) { CFRelease(interfacePrivate->name); } interfacePrivate->name = name;
if (name != NULL) { CFRetain(name); } if (interfacePrivate->localized_name != NULL) { CFRelease(interfacePrivate->localized_name); } interfacePrivate->localized_name = name;}
__private_extern__CFStringRef__SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { return NULL; }
return interfacePrivate->name;}
__private_extern__CFStringRef__SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (interfacePrivate->name == NULL) { interfacePrivate->name = copy_display_name(interface, FALSE, FALSE); }
return interfacePrivate->name;}
CFStringRefSCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
if (interfacePrivate->localized_name == NULL) { interfacePrivate->localized_name = copy_display_name(interface, TRUE, FALSE); }
return interfacePrivate->localized_name;}
__private_extern__CFPropertyListRef__SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface, CFStringRef overrideType){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFPropertyListRef overrides = NULL;
if (interfacePrivate->overrides != NULL) { overrides = CFDictionaryGetValue(interfacePrivate->overrides, overrideType); }
return overrides;}
CFTypeIDSCNetworkInterfaceGetTypeID(void){ pthread_once(&initialized, __SCNetworkInterfaceInitialize); /* initialize runtime */ return __kSCNetworkInterfaceTypeID;}
__private_extern__Boolean__SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface, CFStringRef defaultType, CFDictionaryRef config, Boolean okToHold){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; Boolean ok = FALSE;
/* initialize runtime (and kSCNetworkInterfaceIPv4) */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (defaultType == NULL) { defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType == NULL) { return FALSE; } }
if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) { config = NULL; }
if (set != NULL) { CFStringRef path;
path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL, // allocator SCNetworkSetGetSetID(set), // set interfacePrivate->entity_device, // interface defaultType); // entity if (path != NULL) { ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE); CFRelease(path); if (ok) { // if configuration has been saved if (interfacePrivate->unsaved != NULL) { CFDictionaryRemoveValue(interfacePrivate->unsaved, defaultType); if (CFDictionaryGetCount(interfacePrivate->unsaved) == 0) { CFRelease(interfacePrivate->unsaved); interfacePrivate->unsaved = NULL; } } } } else { if (okToHold) { if (config == NULL) { // remember that we are clearing the configuration config = (CFDictionaryRef)kCFNull; }
if (interfacePrivate->unsaved == NULL) { interfacePrivate->unsaved = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(interfacePrivate->unsaved, defaultType, config); ok = TRUE; } else { _SCErrorSet(kSCStatusNoKey); } } }
return ok;}
__private_extern__Boolean__SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFStringRef extendedType, CFDictionaryRef config, Boolean okToHold){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; Boolean ok = FALSE; CFArrayRef paths;
/* initialize runtime (and kSCNetworkInterfaceIPv4) */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (extendedType == NULL) { extendedType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (extendedType == NULL) { return FALSE; } }
if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) { config = NULL; }
paths = copyConfigurationPaths(interfacePrivate, extendedType); if (paths != NULL) { CFIndex i; CFIndex n;
n = CFArrayGetCount(paths); for (i = 0; i < n; i++) { CFStringRef path;
path = CFArrayGetValueAtIndex(paths, i); ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE); if (!ok) { break; } }
if (ok) { // if configuration has been saved if (interfacePrivate->unsaved != NULL) { CFDictionaryRemoveValue(interfacePrivate->unsaved, extendedType); if (CFDictionaryGetCount(interfacePrivate->unsaved) == 0) { CFRelease(interfacePrivate->unsaved); interfacePrivate->unsaved = NULL; } } }
CFRelease(paths); } else { if (okToHold) { if (config == NULL) { // remember that we are clearing the configuration config = (CFDictionaryRef)kCFNull; }
if (interfacePrivate->unsaved == NULL) { interfacePrivate->unsaved = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(interfacePrivate->unsaved, extendedType, config); ok = TRUE; } else { _SCErrorSet(kSCStatusNoKey); } }
return ok;}
BooleanSCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFDictionaryRef config){ CFStringRef defaultType; Boolean ok;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType == NULL) { return FALSE; }
ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, FALSE); if (ok) { SC_log(LOG_DEBUG, "SCNetworkInterfaceSetConfiguration(): %@ -> %@", interface, config != NULL ? config : (CFDictionaryRef)CFSTR("NULL")); }
return ok;}
BooleanSCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface, CFStringRef extendedType, CFDictionaryRef config){ Boolean ok;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, TRUE)) { return FALSE; }
ok = __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, FALSE); if (ok) { SC_log(LOG_DEBUG, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@", interface, config != NULL ? config : (CFDictionaryRef)CFSTR("NULL")); }
return ok;}
#pragma mark -#pragma mark SCNetworkInterface [Refresh Configuration] API
Boolean_SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName){ CFStringRef key; Boolean ok = FALSE;
if (!isA_CFString(ifName)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, ifName, kSCEntNetRefreshConfiguration); ok = SCDynamicStoreNotifyValue(NULL, key); CFRelease(key); return ok;}
static Boolean__SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs, CFStringRef ifName){ CFDataRef data = NULL; Boolean ok; SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; uint32_t status = kSCStatusOK; CFDataRef reply = NULL;
if (prefsPrivate->helper_port == MACH_PORT_NULL) { ok = __SCPreferencesCreate_helper(prefs); if (!ok) { return FALSE; } }
// serialize the interface name ok = _SCSerializeString(ifName, &data, NULL, NULL); if (!ok) { goto fail; }
// have the helper "refresh" the configuration status = kSCStatusOK; reply = NULL; ok = _SCHelperExec(prefsPrivate->helper_port, SCHELPER_MSG_INTERFACE_REFRESH, data, &status, NULL); if (data != NULL) CFRelease(data); if (!ok) { goto fail; }
if (status != kSCStatusOK) { goto error; }
return TRUE;
fail :
// close helper if (prefsPrivate->helper_port != MACH_PORT_NULL) { _SCHelperClose(&prefsPrivate->helper_port); }
status = kSCStatusAccessError;
error :
// return error _SCErrorSet(status); return FALSE;}
BooleanSCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface){ CFStringRef ifName; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
ifName = SCNetworkInterfaceGetBSDName(interface); if (ifName == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
if (interfacePrivate->prefs != NULL) { SCPreferencesRef prefs = interfacePrivate->prefs; SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs;
if (prefsPrivate->authorizationData != NULL) { return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs, ifName); } }
return _SCNetworkInterfaceForceConfigurationRefresh(ifName);}
#if !TARGET_OS_IPHONEBooleanSCNetworkInterfaceRefreshConfiguration(CFStringRef ifName){ return _SCNetworkInterfaceForceConfigurationRefresh(ifName);}#endif // !TARGET_OS_IPHONE
#pragma mark -#pragma mark SCNetworkInterface Password APIs
static CFStringRefgetPasswordID(CFDictionaryRef config, CFStringRef serviceID){ CFStringRef unique_id = NULL;
if (config != NULL) { CFStringRef encryption;
encryption = CFDictionaryGetValue(config, kSCPropNetPPPAuthPasswordEncryption); if (isA_CFString(encryption) && CFEqual(encryption, kSCValNetPPPAuthPasswordEncryptionKeychain)) { unique_id = CFDictionaryGetValue(config, kSCPropNetPPPAuthPassword); } } if (unique_id == NULL) { unique_id = serviceID; }
return unique_id;}
static CFStringRefcopySharedSecretID(CFDictionaryRef config, CFStringRef serviceID){ CFMutableStringRef shared_id = NULL;
if (config != NULL) { CFStringRef encryption;
encryption = CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecretEncryption); if (isA_CFString(encryption) && CFEqual(encryption, kSCValNetIPSecSharedSecretEncryptionKeychain)) { shared_id = (CFMutableStringRef)CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecret); if (shared_id != NULL) { CFRetain(shared_id); } } }
if (shared_id == NULL) { CFStringRef unique_id;
unique_id = getPasswordID(config, serviceID); shared_id = CFStringCreateMutableCopy(NULL, 0, unique_id); CFStringAppend(shared_id, CFSTR(".SS")); }
return shared_id;}
static CFStringRefcopyXAuthID(CFDictionaryRef config, CFStringRef serviceID){ CFMutableStringRef xauth_id = NULL;
if (config != NULL) { CFStringRef encryption;
encryption = CFDictionaryGetValue(config, kSCPropNetIPSecXAuthPasswordEncryption); if (isA_CFString(encryption) && CFEqual(encryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain)) { xauth_id = (CFMutableStringRef)CFDictionaryGetValue(config, kSCPropNetIPSecXAuthPassword); if (xauth_id != NULL) { CFRetain(xauth_id); } } }
if (xauth_id == NULL) { CFStringRef unique_id;
unique_id = getPasswordID(config, serviceID); xauth_id = CFStringCreateMutableCopy(NULL, 0, unique_id); CFStringAppend(xauth_id, CFSTR(".XAUTH")); }
return xauth_id;}
static BooleancheckInterfacePassword(SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType, SCPreferencesRef *prefs, CFStringRef *serviceID){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!isA_SCNetworkInterface(interface)) { goto error; }
*serviceID = interfacePrivate->serviceID; if (*serviceID == NULL) { goto error; }
*prefs = interfacePrivate->prefs; if (*prefs == NULL) { goto error; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) { // if PPP break; }
goto error; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) { interface = SCNetworkInterfaceGetInterface(interface); if (interface != NULL) { interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) { // if PPP->L2TP interface break; } } } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) { // if IPSec interface break; }
goto error; }
case kSCNetworkInterfacePasswordTypeEAPOL : { break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) { // if IPSec interface break; }
goto error; }
case kSCNetworkInterfacePasswordTypeVPN : { CFStringRef interfaceType;
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) { // if VPN interface break; }
goto error; }
default : break; }
return TRUE;
error :
_SCErrorSet(kSCStatusInvalidArgument); return FALSE;}
BooleanSCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType){ Boolean exists = FALSE; SCPreferencesRef prefs = NULL; CFStringRef serviceID = NULL;
if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) { return FALSE; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFDictionaryRef config; CFStringRef unique_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID unique_id = getPasswordID(config, serviceID);
// check exists = __extract_password(prefs, config, kSCPropNetPPPAuthPassword, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain, unique_id, NULL); break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFDictionaryRef config; Boolean extended; CFStringRef shared_id;
// get configuration extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP); if (extended) { config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec); } else { config = SCNetworkInterfaceGetConfiguration(interface); }
// get sharedSecret ID shared_id = copySharedSecretID(config, serviceID);
// check exists = __extract_password(prefs, config, kSCPropNetIPSecSharedSecret, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain, shared_id, NULL); CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeEAPOL : { CFDictionaryRef config; CFStringRef unique_id = NULL;
// get configuration config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
// get 802.1X identifier if (config != NULL) { unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID); } if (!isA_CFString(unique_id)) { return FALSE; }
// check password exists = _SCPreferencesSystemKeychainPasswordItemExists(prefs, unique_id); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFDictionaryRef config; CFStringRef xauth_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get XAuth ID xauth_id = copyXAuthID(config, serviceID);
// check exists = __extract_password(prefs, config, kSCPropNetIPSecXAuthPassword, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain, xauth_id, NULL); CFRelease(xauth_id); break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFDictionaryRef config; CFStringRef vpn_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID vpn_id = getPasswordID(config, serviceID);
// check exists = __extract_password(prefs, config, kSCPropNetVPNAuthPassword, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain, vpn_id, NULL); break; }
default : _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return exists;}
CFDataRefSCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType){ CFDataRef password = NULL; SCPreferencesRef prefs = NULL; CFStringRef serviceID = NULL;
if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) { return NULL; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFDictionaryRef config; CFStringRef unique_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID unique_id = getPasswordID(config, serviceID);
// extract (void) __extract_password(prefs, config, kSCPropNetPPPAuthPassword, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain, unique_id, &password); break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFDictionaryRef config; Boolean extended; CFStringRef shared_id;
// get configuration extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP); if (extended) { config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec); } else { config = SCNetworkInterfaceGetConfiguration(interface); }
// get sharedSecret ID shared_id = copySharedSecretID(config, serviceID);
// extract (void) __extract_password(prefs, config, kSCPropNetIPSecSharedSecret, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain, shared_id, &password);
CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeEAPOL : { CFDictionaryRef config; CFStringRef unique_id = NULL;
// get configuration config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
// get 802.1X identifier if (config != NULL) { unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID); } if (!isA_CFString(unique_id)) { _SCErrorSet(kSCStatusFailed); return NULL; }
// copy password password = _SCPreferencesSystemKeychainPasswordItemCopy(prefs, unique_id); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFDictionaryRef config; CFStringRef xauth_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get XAuth ID xauth_id = copyXAuthID(config, serviceID);
// extract (void) __extract_password(prefs, config, kSCPropNetIPSecXAuthPassword, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain, xauth_id, &password); CFRelease(xauth_id); break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFDictionaryRef config; CFStringRef vpn_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID vpn_id = getPasswordID(config, serviceID);
// extract (void) __extract_password(prefs, config, kSCPropNetVPNAuthPassword, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain, vpn_id, &password); break; }
default : _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
return password;}
BooleanSCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType){ Boolean ok = FALSE; SCPreferencesRef prefs = NULL; CFStringRef serviceID = NULL;
if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) { return FALSE; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { CFDictionaryRef config; CFDictionaryRef newConfig = NULL; CFStringRef unique_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID unique_id = getPasswordID(config, serviceID);
// remove password ok = __remove_password(prefs, config, kSCPropNetPPPAuthPassword, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain, unique_id, &newConfig); if (ok) { ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); if (newConfig != NULL) CFRelease(newConfig); }
break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFDictionaryRef config; Boolean extended; CFDictionaryRef newConfig = NULL; CFStringRef shared_id;
// get configuration extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP); if (extended) { config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec); } else { config = SCNetworkInterfaceGetConfiguration(interface); }
// get sharedSecret ID shared_id = copySharedSecretID(config, serviceID);
// remove password ok = __remove_password(prefs, config, kSCPropNetIPSecSharedSecret, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain, shared_id, &newConfig); if (ok) { if (extended) { ok = SCNetworkInterfaceSetExtendedConfiguration(interface, kSCEntNetIPSec, newConfig); } else { ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); } if (newConfig != NULL) CFRelease(newConfig); }
CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeEAPOL : { CFDictionaryRef config; CFStringRef unique_id = NULL;
// get configuration config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
// get 802.1X identifier if (config != NULL) { unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID); } if (!isA_CFString(unique_id)) { _SCErrorSet(kSCStatusFailed); return FALSE; }
// remove password ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { CFDictionaryRef config; CFDictionaryRef newConfig = NULL; CFStringRef xauth_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get XAuth ID xauth_id = copyXAuthID(config, serviceID);
// remove password ok = __remove_password(prefs, config, kSCPropNetIPSecXAuthPassword, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain, xauth_id, &newConfig); if (ok) { ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); if (newConfig != NULL) CFRelease(newConfig); }
CFRelease(xauth_id); break; }
case kSCNetworkInterfacePasswordTypeVPN : { CFDictionaryRef config; CFDictionaryRef newConfig = NULL; CFStringRef vpn_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID vpn_id = getPasswordID(config, serviceID);
// remove password ok = __remove_password(prefs, config, kSCPropNetVPNAuthPassword, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain, vpn_id, &newConfig); if (ok) { ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); if (newConfig != NULL) CFRelease(newConfig); } break; }
default : _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
return ok;}
BooleanSCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface, SCNetworkInterfacePasswordType passwordType, CFDataRef password, CFDictionaryRef options){ CFStringRef account = NULL; CFDictionaryRef config; CFStringRef description = NULL; CFStringRef label = NULL; Boolean ok = FALSE; SCPreferencesRef prefs = NULL; CFStringRef serviceID = NULL;
if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) { return FALSE; }
switch (passwordType) { case kSCNetworkInterfacePasswordTypePPP : { SCNetworkServiceRef service = NULL; CFStringRef unique_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID unique_id = getPasswordID(config, serviceID);
// get "Account", "Name", "Kind" if (config != NULL) { // auth name --> keychain "Account" account = CFDictionaryGetValue(config, kSCPropNetPPPAuthName);
// PPP [user defined] "name" --> keychain "Name" label = CFDictionaryGetValue(config, kSCPropUserDefinedName); }
if (label == NULL) { // service name --> keychain "Name" service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL, prefs, serviceID, interface);
label = SCNetworkServiceGetName(service); if (label == NULL) { // interface name --> keychain "Name" label = SCNetworkInterfaceGetLocalizedDisplayName(interface); } }
if (bundle != NULL) { // "PPP Password" --> keychain "Kind" description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"), CFSTR("PPP Password"), NULL); }
// store password ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs, unique_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("PPP Password"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kSCPropNetPPPAuthPassword, unique_id); CFDictionarySetValue(newConfig, kSCPropNetPPPAuthPasswordEncryption, kSCValNetPPPAuthPasswordEncryptionKeychain); ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); CFRelease(newConfig); }
if (description != NULL) CFRelease(description); if (service != NULL) CFRelease(service); break; }
case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : { CFDictionaryRef baseConfig = NULL; Boolean extended; SCNetworkServiceRef service = NULL; CFStringRef shared_id;
// get configuration extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP); config = SCNetworkInterfaceGetConfiguration(interface); if (extended) { baseConfig = config; config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec); }
// get sharedSecret ID shared_id = copySharedSecretID(config, serviceID);
// get "Account", "Name", "Kind" if (config != NULL) { CFStringRef localIdentifier; CFStringRef localIdentifierType;
if (CFDictionaryGetValueIfPresent(config, kSCPropNetIPSecLocalIdentifierType, (const void **)&localIdentifierType) && CFEqual(localIdentifierType, kSCValNetIPSecLocalIdentifierTypeKeyID) && CFDictionaryGetValueIfPresent(config, kSCPropNetIPSecLocalIdentifier, (const void **)&localIdentifier) && isA_CFString(localIdentifier)) { // local identifier --> keychain "Account" account = localIdentifier; }
// PPP [user defined] "name" --> keychain "Name" if (!extended) { label = CFDictionaryGetValue(config, kSCPropUserDefinedName); } else { if (baseConfig != NULL) { label = CFDictionaryGetValue(baseConfig, kSCPropUserDefinedName); } } }
if (label == NULL) { // service name --> keychain "Name" service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL, prefs, serviceID, interface);
label = SCNetworkServiceGetName(service); if (label == NULL) { // interface name --> keychain "Name" label = SCNetworkInterfaceGetLocalizedDisplayName(interface); } }
if (bundle != NULL) { // "IPSec Shared Secret" --> keychain "Kind" description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"), CFSTR("IPSec Shared Secret"), NULL); }
// set password ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs, shared_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("IPSec Shared Secret"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig = NULL;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kSCPropNetIPSecSharedSecret, shared_id); CFDictionarySetValue(newConfig, kSCPropNetIPSecSharedSecretEncryption, kSCValNetIPSecSharedSecretEncryptionKeychain); if (extended) { ok = SCNetworkInterfaceSetExtendedConfiguration(interface, kSCEntNetIPSec, newConfig); } else { ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); } CFRelease(newConfig); }
if (description != NULL) CFRelease(description); if (service != NULL) CFRelease(service); CFRelease(shared_id); break; }
case kSCNetworkInterfacePasswordTypeEAPOL : { CFStringRef account = NULL; CFStringRef unique_id = NULL;
// get configuration config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
// get 802.1X identifier if (config != NULL) { unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID); unique_id = isA_CFString(unique_id); } if (unique_id != NULL) { CFRetain(unique_id); } else { CFUUIDRef uuid;
uuid = CFUUIDCreate(NULL); unique_id = CFUUIDCreateString(NULL, uuid); CFRelease(uuid); }
// 802.1x UserName --> keychain "Account" if (config != NULL) { account = CFDictionaryGetValue(config, kEAPClientPropUserName); }
// get "Name", "Kind" if (bundle != NULL) { CFStringRef interface_name;
// "Network Connection (%@)" --> keychain "Name" interface_name = SCNetworkInterfaceGetLocalizedDisplayName(interface); if (interface_name != NULL) { CFStringRef label_fmt;
label_fmt = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"), CFSTR("Network Connection (%@)"), NULL); label = CFStringCreateWithFormat(NULL, NULL, label_fmt, interface_name); CFRelease(label_fmt); } else { label = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"), CFSTR("Network Connection"), NULL); }
// "802.1X Password" --> keychain "Kind" description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_EAPOL"), CFSTR("802.1X Password"), NULL); }
// set password ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs, unique_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("802.1X Password"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig = NULL;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kEAPClientPropUserPasswordKeychainItemID, unique_id); ok = SCNetworkInterfaceSetExtendedConfiguration(interface, kSCEntNetEAPOL, newConfig); CFRelease(newConfig); }
CFRelease(unique_id); if (label != NULL) CFRelease(label); if (description != NULL) CFRelease(description); break; }
case kSCNetworkInterfacePasswordTypeIPSecXAuth : { SCNetworkServiceRef service = NULL; CFStringRef xauth_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get XAuth ID xauth_id = copyXAuthID(config, serviceID);
// get "Account", "Name", "Kind" if (config != NULL) { // auth name --> keychain "Account" account = CFDictionaryGetValue(config, kSCPropNetIPSecXAuthName);
// IPSec [user defined] "name" --> keychain "Name" label = CFDictionaryGetValue(config, kSCPropUserDefinedName); }
if (label == NULL) { // service name --> keychain "Name" service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL, prefs, serviceID, interface);
label = SCNetworkServiceGetName(service); if (label == NULL) { // interface name --> keychain "Name" label = SCNetworkInterfaceGetLocalizedDisplayName(interface); } }
if (bundle != NULL) { // "IPSec XAuth Password" --> keychain "Kind" description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"), CFSTR("IPSec XAuth Password"), NULL); }
// store password ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs, xauth_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("IPSec XAuth Password"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kSCPropNetIPSecXAuthPassword, xauth_id); CFDictionarySetValue(newConfig, kSCPropNetIPSecXAuthPasswordEncryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain); ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); CFRelease(newConfig); }
CFRelease(xauth_id); if (description != NULL) CFRelease(description); if (service != NULL) CFRelease(service); break; }
case kSCNetworkInterfacePasswordTypeVPN : { SCNetworkServiceRef service = NULL; CFStringRef vpn_id;
// get configuration config = SCNetworkInterfaceGetConfiguration(interface);
// get serviceID vpn_id = getPasswordID(config, serviceID);
// get "Account", "Name", "Kind" if (config != NULL) { // auth name --> keychain "Account" account = CFDictionaryGetValue(config, kSCPropNetVPNAuthName);
// VPN [user defined] "name" --> keychain "Name" label = CFDictionaryGetValue(config, kSCPropUserDefinedName); }
if (label == NULL) { // service name --> keychain "Name" service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL, prefs, serviceID, interface);
label = SCNetworkServiceGetName(service); if (label == NULL) { // interface name --> keychain "Name" label = SCNetworkInterfaceGetLocalizedDisplayName(interface); } }
if (bundle != NULL) { // "VPN Password" --> keychain "Kind" description = CFBundleCopyLocalizedString(bundle, CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"), CFSTR("VPN Password"), NULL); }
// store password ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs, vpn_id, (label != NULL) ? label : CFSTR("Network Connection"), (description != NULL) ? description : CFSTR("VPN Password"), account, password, options); if (ok) { CFMutableDictionaryRef newConfig;
if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newConfig, kSCPropNetVPNAuthPassword, vpn_id); CFDictionarySetValue(newConfig, kSCPropNetVPNAuthPasswordEncryption, kSCValNetVPNAuthPasswordEncryptionKeychain); ok = SCNetworkInterfaceSetConfiguration(interface, newConfig); CFRelease(newConfig); }
if (description != NULL) CFRelease(description); if (service != NULL) CFRelease(service); break; }
default : _SCErrorSet(kSCStatusInvalidArgument); break; }
return ok;}
#pragma mark -#pragma mark SCNetworkInterface [Advisory] SPIs#if TARGET_OS_SIMULATORBooleanSCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface, SCNetworkInterfaceAdvisory advisory, CFStringRef reason){#pragma unused(interface)#pragma unused(advisory)#pragma unused(reason) return (FALSE);}
BooleanSCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface){#pragma unused(interface) return (FALSE);}
CFStringRefSCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface){#pragma unused(interface) return (NULL);}
#else /* TARGET_OS_SIMULATOR */BooleanSCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface, SCNetworkInterfaceAdvisory advisory, CFStringRef reason){ IPMonitorControlRef control; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFStringRef ifName;
ifName = SCNetworkInterfaceGetBSDName(interface); if (ifName == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } control = interfacePrivate->IPMonitorControl; if (control == NULL) { control = IPMonitorControlCreate(); if (control == NULL) { _SCErrorSet(kSCStatusFailed); return (FALSE); } interfacePrivate->IPMonitorControl = control; } return IPMonitorControlSetInterfaceAdvisory(control, ifName, advisory, reason);}
BooleanSCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface){ IPMonitorControlRef control; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFStringRef ifName;
ifName = SCNetworkInterfaceGetBSDName(interface); if (ifName == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } control = interfacePrivate->IPMonitorControl; if (control == NULL) { control = IPMonitorControlCreate(); if (control == NULL) { _SCErrorSet(kSCStatusFailed); return (FALSE); } interfacePrivate->IPMonitorControl = control; } return IPMonitorControlInterfaceAdvisoryIsSet(control, ifName);}
CFStringRefSCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface){ CFStringRef ifName;
ifName = SCNetworkInterfaceGetBSDName(interface); if (ifName == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return (NULL); } return IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifName);}#endif /* TARGET_OS_SIMULATOR */
#pragma mark -#pragma mark SCNetworkInterface [InterfaceNamer] SPIs
CFDictionaryRef_SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface){ CFMutableDictionaryRef info; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFStringRef name;
if (interface == NULL) { return NULL; }
info = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// add non-localized interface name name = __SCNetworkInterfaceGetNonLocalizedDisplayName(interface); if (name != NULL) { CFDictionaryAddValue(info, kSCPropUserDefinedName, name); }
// add USB info if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {#if !TARGET_OS_SIMULATOR if (interfacePrivate->usb.name != NULL) { CFDictionaryAddValue(info, CFSTR(kUSBProductString), interfacePrivate->usb.name); } if (interfacePrivate->usb.vid != NULL) { CFDictionaryAddValue(info, CFSTR(kUSBVendorID), interfacePrivate->usb.vid); } if (interfacePrivate->usb.pid != NULL) { CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid); }#endif // !TARGET_OS_SIMULATOR }
if (CFDictionaryGetCount(info) == 0) { // do not return an empty dictionary CFRelease(info); info = NULL; }
return info;}
SCNetworkInterfaceRef_SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj){ SCNetworkInterfaceRef interface = NULL;
/* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (IOObjectConformsTo(if_obj, kIONetworkInterfaceClass)) { interface = createInterface(if_obj, processNetworkInterface, NULL); } else if (IOObjectConformsTo(if_obj, kIOSerialBSDServiceValue)) { interface = createInterface(if_obj, processSerialInterface, kSCNetworkInterfaceHiddenPortKey); }
return interface;}
CFStringRef_SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->configurationAction;}
CFDataRef_SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->address;}
CFStringRef_SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->prefix;}
CFNumberRef_SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->type;}
CFNumberRef_SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->unit;}
static voidupdate_ift_family(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
// note: family/subfamily are not in IORegistry, fetch with ioctl()
if ((interfacePrivate->family == NULL) && (interfacePrivate->subfamily == NULL)) { CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface); struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr)); if ((bsdName != NULL) && _SC_cfstring_to_cstring(bsdName, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) != NULL) { int s;
s = socket(AF_INET, SOCK_DGRAM, 0); if (s != -1) { if (ioctl(s, SIOCGIFTYPE, (caddr_t)&ifr) == -1) { ifr.ifr_type.ift_family = 0; ifr.ifr_type.ift_subfamily = 0; } close(s); } }
interfacePrivate->family = CFNumberCreate(NULL, kCFNumberSInt32Type, &ifr.ifr_type.ift_family); interfacePrivate->subfamily = CFNumberCreate(NULL, kCFNumberSInt32Type, &ifr.ifr_type.ift_subfamily); }}
CFNumberRef_SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
// note: family not in IORegistry, fetch with ioctl()
if (interfacePrivate->family == NULL) { update_ift_family(interface); }
return interfacePrivate->family;}
CFNumberRef_SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
// note: subfamily not in IORegistry, fetch with ioctl()
if (interfacePrivate->subfamily == NULL) { update_ift_family(interface); }
return interfacePrivate->subfamily;}
CFStringRef_SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->path;}
uint64_t_SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->entryID;}
__private_extern__Boolean__SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->active;}
Boolean_SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->builtin;}
Boolean_SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->trustRequired;}
#pragma mark -#pragma mark SCNetworkInterface SPIs
#if TARGET_OS_OSX
SCNetworkInterfaceRef_SCNetworkInterfaceCopyBTPANInterface(void){ CFDictionaryRef dict; SCNetworkInterfaceRef interface = NULL; CFStringRef key;
key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin); dict = SCDynamicStoreCopyValue(NULL, key); CFRelease(key); if (dict != NULL) { CFDataRef addr; CFStringRef if_name; SCNetworkInterfacePrivateRef interfacePrivate;
if (isA_CFDictionary(dict) && CFDictionaryGetValueIfPresent(dict, kInterfaceNamerKey_BT_PAN_Name, (const void **)&if_name) && isA_CFString(if_name)) { CFMutableDictionaryRef entity;
entity = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(entity, kSCPropNetInterfaceType, kSCValNetInterfaceTypeEthernet); CFDictionarySetValue(entity, kSCPropNetInterfaceDeviceName, if_name); CFDictionarySetValue(entity, kSCPropUserDefinedName, CFSTR(BT_PAN_NAME)); interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, NULL); CFRelease(entity); }
interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if ((interfacePrivate != NULL) && (interfacePrivate->address == NULL) && CFDictionaryGetValueIfPresent(dict, kInterfaceNamerKey_BT_PAN_Mac, (const void **)&addr) && isA_CFData(addr)) { interfacePrivate->address = CFRetain(addr); }
CFRelease(dict); }
return interface;}#endif // TARGET_OS_OSX
CFStringRef_SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface){ io_registry_entry_t device; io_iterator_t device_iterator = MACH_PORT_NULL; CFStringRef device_path = NULL; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; kern_return_t kr; CFStringRef match_keys[2]; CFTypeRef match_vals[2]; CFDictionaryRef match_dict; CFDictionaryRef matching;
if (interfacePrivate->entity_device == NULL) { return NULL; }
if (interfacePrivate->entity_device_unique == NULL) { goto done; }
match_keys[0] = CFSTR(kIOTTYBaseNameKey); match_vals[0] = interfacePrivate->entity_device; match_dict = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
match_keys[0] = CFSTR(kIOProviderClassKey); match_vals[0] = CFSTR(kIOSerialBSDServiceValue); match_keys[1] = CFSTR(kIOPropertyMatchKey); match_vals[1] = match_dict; matching = CFDictionaryCreate(NULL, (const void **)match_keys, (const void **)match_vals, sizeof(match_keys)/sizeof(match_keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(match_dict);
// note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices kr = IOServiceGetMatchingServices(masterPort, matching, &device_iterator); if (kr != kIOReturnSuccess) { SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr); goto done; }
while ((device_path == NULL) && ((device = IOIteratorNext(device_iterator)) != MACH_PORT_NULL)) { CFDictionaryRef overrides;
overrides = IORegistryEntrySearchCFProperty(device, kIOServicePlane, kSCNetworkInterfaceNetworkConfigurationOverridesKey, NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (overrides != NULL) { CFDictionaryRef modemOverrides;
modemOverrides = CFDictionaryGetValue(overrides, kSCEntNetModem); if (modemOverrides != NULL) { CFRetain(modemOverrides); } CFRelease(overrides); overrides = modemOverrides; } if (overrides == NULL) { overrides = IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR("DeviceModemOverrides"), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); } if (overrides != NULL) { if (isA_CFDictionary(overrides)) { CFStringRef matchIdentifier;
matchIdentifier = CFDictionaryGetValue(overrides, CFSTR("UniqueIdentifier")); if (isA_CFString(matchIdentifier) && CFEqual(interfacePrivate->entity_device_unique, matchIdentifier)) { device_path = IORegistryEntryCreateCFProperty(device, CFSTR(kIOTTYDeviceKey), NULL, 0); } } CFRelease(overrides); } IOObjectRelease(device); }
IOObjectRelease(device_iterator);
done :
if (device_path == NULL) { // if we haven't found an exact match to our UniqueIdentifier // so we simply return the base name. device_path = SCNetworkInterfaceGetBSDName(interface); if (device_path != NULL) { CFRetain(device_path); } }
return device_path;}
#pragma mark -
Boolean_SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface){#if TARGET_OS_SIMULATOR#pragma unused(interface)#else // TARGET_OS_SIMULATOR SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
if (!_SCNetworkInterfaceIsHiddenConfiguration(interface)) { // if not HiddenConfiguration return FALSE; }
if ((interfacePrivate->overrides == NULL) || (!CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) && !CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) { // if no [IPv4/IPv6] configuration overrides return FALSE; }
if (_SCNetworkInterfaceIsBuiltin(interface)) { // if built-in (and overrides are present) return TRUE; }
if (_SCNetworkInterfaceIsCarPlay(interface)) { // if CarPlay (and overrides are present) return TRUE; }
if (isA_CFNumber(interfacePrivate->usb.vid)) { int vid;
if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) && (vid == kIOUSBVendorIDAppleComputer)) { // if Apple interface (and overrides are present) return TRUE; } }#endif // TARGET_OS_SIMULATOR
return FALSE;}
Boolean_SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return (interfacePrivate->sort_order == kSortBluetoothPAN_GN);}
Boolean_SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return (interfacePrivate->sort_order == kSortBluetoothPAN_NAP);}
Boolean_SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return (interfacePrivate->sort_order == kSortBluetoothPAN_U);}
Boolean_SCNetworkInterfaceIsCarPlay(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return (interfacePrivate->sort_order == kSortCarPlay);}
Boolean_SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return interfacePrivate->hidden;}
Boolean_SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
return (interfacePrivate->sort_order == kSortTethered);}
Boolean_SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface){ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFStringRef interfaceType;
if (!isA_SCNetworkInterface(interface)) { return FALSE; }
interfaceType = SCNetworkInterfaceGetInterfaceType(interface); if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) { CFIndex i; CFArrayRef members; CFIndex n;
members = SCBridgeInterfaceGetMemberInterfaces(interface); n = (members != NULL) ? CFArrayGetCount(members) : 0; if (n == 0) { // if an empty bridge return FALSE; }
for (i = 0; i < n; i++) { SCNetworkInterfaceRef member; SCNetworkInterfacePrivateRef memberPrivate;
member = CFArrayGetValueAtIndex(members, i); memberPrivate = (SCNetworkInterfacePrivateRef)member; if (memberPrivate->sort_order != kSortThunderbolt) { return FALSE; } }
// if Ethernet Bridge interface with only Thunderbolt [IP] members return TRUE; }
return (interfacePrivate->sort_order == kSortThunderbolt);}
#pragma mark -
CFDictionaryRefSCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface){ CFDictionaryRef policy;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; }
policy = __SCNetworkInterfaceGetConfiguration(interface, kSCEntNetQoSMarkingPolicy); if (policy == NULL) { _SCErrorSet(kSCStatusOK); }
return policy;}
BooleanSCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface, CFDictionaryRef policy){ Boolean ok;
if (!isA_SCNetworkInterface(interface)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; }
ok = __SCNetworkInterfaceSetConfiguration(interface, kSCEntNetQoSMarkingPolicy, policy, FALSE); if (ok) { SC_log(LOG_DEBUG, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@", interface, policy != NULL ? policy : (CFDictionaryRef)CFSTR("NULL")); }
return ok;}
#pragma mark -#pragma mark SCNetworkInterface [internal] SPIs
__private_extern__SCNetworkInterfacePrivateRef__SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator, SCNetworkInterfaceRef interface, SCPreferencesRef prefs, CFStringRef serviceID){#pragma unused(allocator) SCNetworkInterfacePrivateRef oldPrivate = (SCNetworkInterfacePrivateRef)interface; SCNetworkInterfacePrivateRef newPrivate;
/* initialize runtime (and kSCNetworkInterfaceIPv4) */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (interface == kSCNetworkInterfaceIPv4) { return (SCNetworkInterfacePrivateRef)CFRetain(interface); }
newPrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, prefs, serviceID); newPrivate->interface_type = oldPrivate->interface_type; if (oldPrivate->interface != NULL) { newPrivate->interface = (SCNetworkInterfaceRef)__SCNetworkInterfaceCreateCopy(NULL, // allocator oldPrivate->interface, // interface prefs, // [new] prefs serviceID); // [new] serviceID } if (oldPrivate->name != NULL) { newPrivate->name = CFRetain(oldPrivate->name); } if (oldPrivate->prefix != NULL) { newPrivate->prefix = CFRetain(oldPrivate->prefix); } if (oldPrivate->localized_name != NULL) { newPrivate->localized_name = CFRetain(oldPrivate->localized_name); } newPrivate->localized_key = oldPrivate->localized_key; if (oldPrivate->localized_arg1 != NULL) { newPrivate->localized_arg1 = CFRetain(oldPrivate->localized_arg1); } if (oldPrivate->localized_arg2 != NULL) { newPrivate->localized_arg2 = CFRetain(oldPrivate->localized_arg2); } if (oldPrivate->unsaved != NULL) { newPrivate->unsaved = CFDictionaryCreateMutableCopy(NULL, 0, oldPrivate->unsaved); } if (oldPrivate->entity_device != NULL) { newPrivate->entity_device = CFRetain(oldPrivate->entity_device); } if (oldPrivate->entity_device_unique != NULL) { newPrivate->entity_device_unique = CFRetain(oldPrivate->entity_device_unique); } newPrivate->entity_type = oldPrivate->entity_type; newPrivate->entity_subtype = oldPrivate->entity_subtype; if (oldPrivate->supported_interface_types != NULL) { newPrivate->supported_interface_types = CFArrayCreateMutableCopy(NULL, 0, oldPrivate->supported_interface_types); } if (oldPrivate->supported_protocol_types != NULL) { newPrivate->supported_protocol_types = CFArrayCreateMutableCopy(NULL, 0, oldPrivate->supported_protocol_types); } if (oldPrivate->address != NULL) { newPrivate->address = CFRetain(oldPrivate->address); } newPrivate->builtin = oldPrivate->builtin; if (oldPrivate->configurationAction != NULL) { newPrivate->configurationAction = CFRetain(oldPrivate->configurationAction); } newPrivate->hidden = oldPrivate->hidden;#if TARGET_OS_IPHONE newPrivate->trustRequired = oldPrivate->trustRequired;#endif // TARGET_OS_IPHONE if (oldPrivate->location != NULL) { newPrivate->location = CFRetain(oldPrivate->location); } if (oldPrivate->path != NULL) { newPrivate->path = CFRetain(oldPrivate->path); } newPrivate->entryID = oldPrivate->entryID; if (oldPrivate->overrides != NULL) { newPrivate->overrides = CFDictionaryCreateMutableCopy(NULL, 0, oldPrivate->overrides); } if (oldPrivate->type != NULL) { newPrivate->type = CFRetain(oldPrivate->type); } if (oldPrivate->unit != NULL) { newPrivate->unit = CFRetain(oldPrivate->unit); } if (oldPrivate->family != NULL) { newPrivate->family = CFRetain(oldPrivate->family); } if (oldPrivate->subfamily != NULL) { newPrivate->subfamily = CFRetain(oldPrivate->subfamily); } if (oldPrivate->usb.name != NULL) { newPrivate->usb.name = CFRetain(oldPrivate->usb.name); } if (oldPrivate->usb.vid != NULL) { newPrivate->usb.vid = CFRetain(oldPrivate->usb.vid); } if (oldPrivate->usb.pid != NULL) { newPrivate->usb.pid = CFRetain(oldPrivate->usb.pid); } newPrivate->sort_order = oldPrivate->sort_order;
newPrivate->supportsBond = oldPrivate->supportsBond; if (oldPrivate->bond.interfaces != NULL) { newPrivate->bond.interfaces = CFRetain(oldPrivate->bond.interfaces); } if (oldPrivate->bond.mode != NULL) { newPrivate->bond.mode = CFRetain(oldPrivate->bond.mode); } if (oldPrivate->bond.options != NULL) { newPrivate->bond.options = CFRetain(oldPrivate->bond.options); }
newPrivate->supportsBridge = oldPrivate->supportsBridge; if (oldPrivate->bridge.interfaces != NULL) { newPrivate->bridge.interfaces = CFRetain(oldPrivate->bridge.interfaces); } if (oldPrivate->bridge.options != NULL) { newPrivate->bridge.options = CFRetain(oldPrivate->bridge.options); }
newPrivate->supportsVLAN = oldPrivate->supportsVLAN; if (oldPrivate->vlan.interface != NULL) { newPrivate->vlan.interface = CFRetain(oldPrivate->vlan.interface); } if (oldPrivate->vlan.tag != NULL) { newPrivate->vlan.tag = CFRetain(oldPrivate->vlan.tag); } if (oldPrivate->vlan.options != NULL) { newPrivate->vlan.options = CFRetain(oldPrivate->vlan.options); }
return newPrivate;}
__private_extern__CFArrayRef__SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface){ CFMutableArrayRef configs;
configs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
while (interface != NULL) { CFStringRef defaultType; CFMutableDictionaryRef interfaceConfiguration;
interfaceConfiguration = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType != NULL) { CFDictionaryRef config; CFArrayRef extendedTypes;
if (set == NULL) { config = __SCNetworkInterfaceGetConfiguration(interface, defaultType); } else { config = __SCNetworkInterfaceGetDefaultConfiguration(set, interface); } if (config == NULL) { config = (CFDictionaryRef)kCFNull; } CFDictionarySetValue(interfaceConfiguration, defaultType, config);
extendedTypes = extendedConfigurationTypes(interface); if (extendedTypes != NULL) { CFIndex i; CFIndex n;
n = CFArrayGetCount(extendedTypes); for (i = 0; i < n; i++) { CFStringRef extendedType;
extendedType = CFArrayGetValueAtIndex(extendedTypes, i); config = __SCNetworkInterfaceGetConfiguration(interface, extendedType); if (config == NULL) { config = (CFDictionaryRef)kCFNull; } CFDictionarySetValue(interfaceConfiguration, extendedType, config); }
CFRelease(extendedTypes); } }
CFArrayAppendValue(configs, interfaceConfiguration); CFRelease(interfaceConfiguration);
interface = SCNetworkInterfaceGetInterface(interface); }
return configs;}
__private_extern__ Boolean__SCNetworkInterfaceIsMember(SCPreferencesRef prefs, SCNetworkInterfaceRef interface){ CFArrayRef interfaces; Boolean match = FALSE; CFMutableSetRef members;
members = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
#if !TARGET_OS_IPHONE // add Bond [member] interfaces interfaces = SCBondInterfaceCopyAll(prefs); if (interfaces != NULL) { __SCBondInterfaceListCollectMembers(interfaces, members); CFRelease(interfaces); }#endif // !TARGET_OS_IPHONE
// add Bridge [member] interfaces interfaces = SCBridgeInterfaceCopyAll(prefs); if (interfaces != NULL) { __SCBridgeInterfaceListCollectMembers(interfaces, members); CFRelease(interfaces); }
if (CFSetGetCount(members) == 0) { goto done; }
while (interface != NULL) { match = CFSetContainsValue(members, interface); if (match) { // if the interface is a member of an // Ethernet Bond or Bridge break; }
interface = SCNetworkInterfaceGetInterface(interface); }
done :
CFRelease(members); return match;}
__private_extern__void__SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface, CFArrayRef configs){ CFIndex i;
for (i = 0; interface != NULL; i++) { CFStringRef defaultType; CFDictionaryRef interfaceConfiguration; Boolean ok;
interfaceConfiguration = (configs != NULL) ? CFArrayGetValueAtIndex(configs, i) : NULL;
defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface); if (defaultType != NULL) { CFDictionaryRef config; CFArrayRef extendedTypes;
config = (interfaceConfiguration != NULL) ? CFDictionaryGetValue(interfaceConfiguration, defaultType) : NULL; if (config == (CFDictionaryRef)kCFNull) { config = NULL; } if (set == NULL) { // if service is not associated with the set ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, TRUE); } else { // apply default configuration to this set ok = __SCNetworkInterfaceSetDefaultConfiguration(set, interface, defaultType, config, TRUE); } if (ok) { SC_log(LOG_DEBUG, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@", interface, defaultType, config != NULL ? config : (CFDictionaryRef)CFSTR("NULL")); } else { SC_log(LOG_INFO, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@", interface, defaultType); }
extendedTypes = extendedConfigurationTypes(interface); if (extendedTypes != NULL) { CFIndex j; CFIndex n;
n = CFArrayGetCount(extendedTypes); for (j = 0; j < n; j++) { CFStringRef extendedType;
extendedType = CFArrayGetValueAtIndex(extendedTypes, j); config = (interfaceConfiguration != NULL) ? CFDictionaryGetValue(interfaceConfiguration, extendedType) : NULL; if (config == (CFDictionaryRef)kCFNull) { config = NULL; } ok = __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, TRUE); if (ok) { SC_log(LOG_DEBUG, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@", interface, extendedType, config != NULL ? config : (CFDictionaryRef)CFSTR("NULL")); } else { SC_log(LOG_INFO, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@", interface, extendedType); } }
CFRelease(extendedTypes); } }
interface = SCNetworkInterfaceGetInterface(interface); }
return;}
SCNetworkInterfaceRef_SCNetworkInterfaceCopyActive(SCDynamicStoreRef store, CFStringRef bsdName){ SCNetworkInterfaceRef interface;
interface = _SCNetworkInterfaceCreateWithBSDName(NULL, bsdName, kIncludeAllVirtualInterfaces); if (interface == NULL) { return NULL; }
if (store != NULL) { SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
CFRetain(store); interfacePrivate->store = store; }
return interface;}
#if !TARGET_OS_SIMULATORSCNetworkServicePrimaryRankSCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface){ IPMonitorControlRef control; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; SCNetworkServicePrimaryRank rank = kSCNetworkServicePrimaryRankDefault;
control = interfacePrivate->IPMonitorControl; if (control != NULL) { CFStringRef ifName;
ifName = SCNetworkInterfaceGetBSDName(interface); if (ifName != NULL) { rank = IPMonitorControlGetInterfacePrimaryRank(control, ifName); } else { _SCErrorSet(kSCStatusInvalidArgument); } } return rank;}
BooleanSCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface, SCNetworkServicePrimaryRank newRank){ IPMonitorControlRef control; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFStringRef ifName;
ifName = SCNetworkInterfaceGetBSDName(interface); if (ifName == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } control = interfacePrivate->IPMonitorControl; if (control == NULL) { control = IPMonitorControlCreate(); if (control == NULL) { _SCErrorSet(kSCStatusFailed); return (FALSE); } interfacePrivate->IPMonitorControl = control; } return IPMonitorControlSetInterfacePrimaryRank(control, ifName, newRank);}
BooleanSCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface){ Boolean disable_until_needed = FALSE; CFNumberRef disable_prop = NULL; CFIndex interfaceIndex; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFArrayRef path_list;
if (interfacePrivate->prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } interfaceIndex = findPerInterfaceConfiguration(interface); if (interfaceIndex == kCFNotFound) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } path_list = copyPerInterfaceConfigurationPaths(interfacePrivate, NULL); if (path_list != NULL) { CFDictionaryRef config; CFStringRef path = CFArrayGetValueAtIndex(path_list, 0);
config = __getPrefsConfiguration(interfacePrivate->prefs, path); CFRelease(path_list); if (config != NULL) { int disable = 0;
disable_prop = CFDictionaryGetValue(config, kSCPropDisableUntilNeeded); disable_prop = isA_CFNumber(disable_prop); if (disable_prop != NULL) { if (CFNumberGetValue(disable_prop, kCFNumberIntType, &disable)) { disable_until_needed = (disable != 0) ? TRUE : FALSE; } else { /* invalid property, ignore it */ disable_prop = NULL; } } } } if (disable_prop == NULL) { disable_until_needed = _SCNetworkInterfaceIsTethered(interface); } _SCErrorSet(kSCStatusOK); return (disable_until_needed);}
Boolean__SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, CFTypeRef disable){ CFIndex count; CFIndex i; CFIndex interfaceIndex; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; Boolean ok = TRUE; CFArrayRef path_list;
if (interfacePrivate->prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } if ((disable != NULL) && !isA_CFNumber(disable)) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } interfaceIndex = findPerInterfaceConfiguration(interface); if (interfaceIndex == kCFNotFound) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } path_list = copyPerInterfaceConfigurationPaths(interfacePrivate, NULL); if (path_list == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return (FALSE); } count = CFArrayGetCount(path_list); for (i = 0; i < count; i++) { CFDictionaryRef config; CFMutableDictionaryRef new_config; CFStringRef path = CFArrayGetValueAtIndex(path_list, i);
config = __getPrefsConfiguration(interfacePrivate->prefs, path); if (config != NULL) { new_config = CFDictionaryCreateMutableCopy(NULL, 0, config); } else { new_config = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } if (disable != NULL) { CFDictionarySetValue(new_config, kSCPropDisableUntilNeeded, disable); } else { CFDictionaryRemoveValue(new_config, kSCPropDisableUntilNeeded); } ok = __setPrefsConfiguration(interfacePrivate->prefs, path, (CFDictionaryGetCount(new_config) > 0) ? new_config : NULL, FALSE); CFRelease(new_config); if (!ok) { break; } } CFRelease(path_list); return (ok);}
BooleanSCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean disable){ Boolean ok; const int one = 1; CFNumberRef num; const int zero = 0;
num = CFNumberCreate(NULL, kCFNumberIntType, disable ? &one : &zero); ok = __SCNetworkInterfaceSetDisableUntilNeededValue(interface, num); CFRelease(num);
return ok;}
#else // !TARGET_OS_SIMULATOR
SCNetworkServicePrimaryRankSCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface){#pragma unused(interface) return (kSCNetworkServicePrimaryRankDefault);}
BooleanSCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface, SCNetworkServicePrimaryRank newRank){#pragma unused(interface)#pragma unused(newRank) _SCErrorSet(kSCStatusInvalidArgument); return (FALSE);}
BooleanSCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface){#pragma unused(interface) return (FALSE);}
Boolean__SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, CFTypeRef disable){#pragma unused(interface)#pragma unused(disable) return (FALSE);}
BooleanSCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean disable){#pragma unused(interface)#pragma unused(disable) _SCErrorSet(kSCStatusInvalidArgument); return (FALSE);}
#endif // !TARGET_OS_SIMULATOR
__private_extern__CFArrayRef // SCNetworkInterfaceRef__SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs){ CFStringRef defaultNetworkInterfacePath = NULL; CFArrayRef if_list; CFMutableArrayRef interfaceList = NULL; SCNetworkInterfaceRef interfaceNamer = NULL;
/* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (ni_prefs == NULL) { defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS); assert(defaultNetworkInterfacePath != NULL); ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath); }
if_list = SCPreferencesGetValue(ni_prefs, INTERFACES); if (isA_CFArray(if_list)) { CFIndex i; CFIndex n = CFArrayGetCount(if_list);
interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < n; i++) { CFDictionaryRef dict;
dict = CFArrayGetValueAtIndex(if_list, i); if (isA_CFDictionary(dict) != NULL) { interfaceNamer = __SCNetworkInterfaceCreateWithStorageEntity(NULL, dict);
if (interfaceNamer != NULL) { CFArrayAppendValue(interfaceList, interfaceNamer); CFRelease(interfaceNamer); } } } }
if (defaultNetworkInterfacePath != NULL) { CFRelease(defaultNetworkInterfacePath); // prefs were created in the function, and hence need to be released CFRelease(ni_prefs); } return interfaceList;}
__private_extern__Boolean__SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs, CFArrayRef interfacesToSave){ CFStringRef defaultNetworkInterfacePath = NULL; Boolean success = FALSE;
if (prefs == NULL) { // TODO: Get the default preferences on the system defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS); assert(defaultNetworkInterfacePath != NULL); prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath); }
if (isA_CFArray(interfacesToSave) == NULL) { SC_log(LOG_INFO, "No interfaces to save"); goto done; } SCPreferencesSetValue(prefs, INTERFACES, interfacesToSave); success = TRUE;done: if (defaultNetworkInterfacePath != NULL) { CFRelease(defaultNetworkInterfacePath); // prefs were created in the function, and hence need to be released CFRelease(prefs); }
return success;}
__private_extern__SCNetworkInterfaceRef__SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator, SCPreferencesRef ni_prefs, CFStringRef bsdName){ CFArrayRef if_list; SCNetworkInterfaceRef interface = NULL; CFStringRef defaultNetworkInterfacePath;
/* initialize runtime */ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (ni_prefs == NULL) { defaultNetworkInterfacePath = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS); ni_prefs = SCPreferencesCreate(allocator, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath); CFRelease(defaultNetworkInterfacePath); } else { CFRetain(ni_prefs); }
if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
if (isA_CFArray(if_list) != NULL) { CFIndex idx; CFIndex count = CFArrayGetCount(if_list);
for (idx = 0; idx < count; idx++) { CFDictionaryRef dict; CFStringRef tmp_bsdName;
dict = CFArrayGetValueAtIndex(if_list, idx); if (isA_CFDictionary(dict) == NULL) { continue; }
tmp_bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName)); if (tmp_bsdName == NULL) { continue; } if (CFEqual(bsdName, tmp_bsdName)) { interface = __SCNetworkInterfaceCreateWithStorageEntity(allocator, dict); break; } } }
CFRelease(ni_prefs); return interface;}
__private_extern__CFDictionaryRef__SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces){ CFMutableDictionaryRef mappingBSDToInterface = NULL; CFStringRef bsdName = NULL; SCNetworkInterfaceRef interface = NULL; CFIndex count;
count = CFArrayGetCount(interfaces); if (count == 0) { SC_log(LOG_INFO, "No interfaces"); return NULL; } mappingBSDToInterface = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
for (CFIndex idx = 0; idx < count; idx++) { interface = (SCNetworkInterfaceRef) CFArrayGetValueAtIndex(interfaces, idx);
bsdName = SCNetworkInterfaceGetBSDName(interface); if (isA_CFString(bsdName) == NULL) { SC_log(LOG_INFO, "No BSD name"); continue; } CFDictionaryAddValue(mappingBSDToInterface, bsdName, interface); } if (CFDictionaryGetCount(mappingBSDToInterface) == 0) { CFRelease(mappingBSDToInterface); mappingBSDToInterface = NULL; SC_log(LOG_INFO, "No mappings"); }
return mappingBSDToInterface;}
__private_extern__ Boolean__SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity){ CFStringRef intfSubtype;
if (entity == NULL) { return FALSE; }
intfSubtype = CFDictionaryGetValue(entity, kSCPropNetInterfaceSubType);#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wdeprecated" if (intfSubtype != NULL && CFEqual(intfSubtype, kSCValNetInterfaceSubTypePPTP)) { return TRUE; }#pragma GCC diagnostic pop
return FALSE;}