123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721 |
- #ifndef _GNU_SOURCE
- #define _GNU_SOURCE
- #endif
- #include <getopt.h> /* getopt_long() */
- #include <linux/sockios.h> /* SIOCSIFNAME */
- #include <fnmatch.h> /* fnmatch() */
- #include "iwlib.h"
- const char DEFAULT_CONF[] = "/etc/iftab";
- const char DEBIAN_CONFIG_FILE[] = "/etc/network/interfaces";
- #ifndef ifr_newname
- #define ifr_newname ifr_ifru.ifru_slave
- #endif
- const int SELECT_MAC = 0;
- const int SELECT_ETHADDR = 1;
- const int SELECT_ARP = 2;
- const int SELECT_LINKTYPE = 3;
- const int SELECT_DRIVER = 4;
- const int SELECT_BUSINFO = 5;
- const int SELECT_FIRMWARE = 6;
- const int SELECT_BASEADDR = 7;
- const int SELECT_IRQ = 8;
- const int SELECT_INTERRUPT = 9;
- const int SELECT_IWPROTO = 10;
- const int SELECT_PCMCIASLOT = 11;
- const int SELECT_SYSFS = 12;
- const int SELECT_PREVNAME = 13;
- #define SELECT_NUM 14
- #define HAS_MAC_EXACT 1
- #define HAS_MAC_FILTER 2
- #define MAX_MAC_LEN 16
- const struct ether_addr zero_mac = {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
- const struct option long_opt[] =
- {
- {"config-file", 1, NULL, 'c' },
- {"debian", 0, NULL, 'd' },
- {"dry-run", 0, NULL, 'D' },
- {"help", 0, NULL, '?' },
- {"interface", 1, NULL, 'i' },
- {"newname", 1, NULL, 'n' },
- {"takeover", 0, NULL, 't' },
- {"udev", 0, NULL, 'u' },
- {"version", 0, NULL, 'v' },
- {"verbose", 0, NULL, 'V' },
- {NULL, 0, NULL, '\0' },
- };
- #define PCMCIA_STAB1 "/var/lib/pcmcia/stab"
- #define PCMCIA_STAB2 "/var/run/stab"
- #define SYSFS_MAX_FILE 8
- #ifndef ARPHRD_IEEE1394
- #define ARPHRD_IEEE1394 24
- #endif
- #ifndef ARPHRD_EUI64
- #define ARPHRD_EUI64 27
- #endif
- #ifndef ARPHRD_IRDA
- #define ARPHRD_IRDA 783
- #endif
- const int weird_mac_len[][2] =
- {
- { ARPHRD_IEEE1394, 8 },
- { ARPHRD_EUI64, 8 },
- { ARPHRD_IRDA, 4 },
- };
- const int weird_mac_len_num = sizeof(weird_mac_len) / sizeof(weird_mac_len[0]);
- #define ETHTOOL_BUSINFO_LEN 32
- struct ethtool_drvinfo {
- __u32 cmd;
- char driver[32];
- char version[32];
- char fw_version[32];
- char bus_info[ETHTOOL_BUSINFO_LEN];
-
- char reserved1[32];
- char reserved2[16];
- __u32 n_stats;
- __u32 testinfo_len;
- __u32 eedump_len;
- __u32 regdump_len;
- };
- #define ETHTOOL_GDRVINFO 0x00000003
- typedef struct if_mapping
- {
-
- struct if_mapping * next;
-
- char ifname[IFNAMSIZ+1];
- char * sysfs_devpath;
- int sysfs_devplen;
-
- int active[SELECT_NUM];
-
- unsigned char mac[MAX_MAC_LEN];
- int mac_len;
- char mac_filter[16*3 + 1];
- unsigned short hw_type;
- char driver[32];
- char bus_info[ETHTOOL_BUSINFO_LEN];
- char fw_version[32];
- unsigned short base_addr;
- unsigned char irq;
- char iwproto[IFNAMSIZ + 1];
- int pcmcia_slot;
- char * sysfs[SYSFS_MAX_FILE];
- char prevname[IFNAMSIZ+1];
- } if_mapping;
- typedef struct add_extra
- {
- char * modif_pos;
- size_t modif_len;
- } parsing_extra;
- typedef int (*mapping_add)(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- typedef int (*mapping_cmp)(struct if_mapping * ifnode,
- struct if_mapping * target);
- typedef int (*mapping_get)(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- typedef struct mapping_selector
- {
- char * name;
- mapping_add add_fn;
- mapping_cmp cmp_fn;
- mapping_get get_fn;
- } mapping_selector;
- typedef struct sysfs_metadata
- {
- char * root;
- int rlen;
- int filenum;
- char * filename[SYSFS_MAX_FILE];
- } sysfs_metadata;
- static int
- mapping_addmac(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpmac(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getmac(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- static int
- mapping_addarp(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmparp(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getarp(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- static int
- mapping_adddriver(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpdriver(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_addbusinfo(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpbusinfo(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_addfirmware(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpfirmware(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getdriverbusinfo(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- static int
- mapping_addbaseaddr(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpbaseaddr(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_addirq(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpirq(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getbaseaddrirq(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- static int
- mapping_addiwproto(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpiwproto(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getiwproto(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- static int
- mapping_addpcmciaslot(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmppcmciaslot(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getpcmciaslot(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- static int
- mapping_addsysfs(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpsysfs(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getsysfs(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- static int
- mapping_addprevname(struct if_mapping * ifnode,
- int * active,
- char * pos,
- size_t len,
- struct add_extra * extra,
- int linenum);
- static int
- mapping_cmpprevname(struct if_mapping * ifnode,
- struct if_mapping * target);
- static int
- mapping_getprevname(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag);
- struct if_mapping * mapping_list = NULL;
- const struct mapping_selector selector_list[] =
- {
-
- { "mac", &mapping_addmac, &mapping_cmpmac, &mapping_getmac },
- { "ethaddr", &mapping_addmac, &mapping_cmpmac, &mapping_getmac },
- { "arp", &mapping_addarp, &mapping_cmparp, &mapping_getarp },
- { "linktype", &mapping_addarp, &mapping_cmparp, &mapping_getarp },
-
- { "driver", &mapping_adddriver, &mapping_cmpdriver,
- &mapping_getdriverbusinfo },
- { "businfo", &mapping_addbusinfo, &mapping_cmpbusinfo,
- &mapping_getdriverbusinfo },
- { "firmware", &mapping_addfirmware, &mapping_cmpfirmware,
- &mapping_getdriverbusinfo },
-
- { "baseaddress", &mapping_addbaseaddr, &mapping_cmpbaseaddr,
- &mapping_getbaseaddrirq },
- { "irq", &mapping_addirq, &mapping_cmpirq, &mapping_getbaseaddrirq },
- { "interrupt", &mapping_addirq, &mapping_cmpirq, &mapping_getbaseaddrirq },
-
- { "iwproto", &mapping_addiwproto, &mapping_cmpiwproto, &mapping_getiwproto },
-
- { "pcmciaslot", &mapping_addpcmciaslot, &mapping_cmppcmciaslot, &mapping_getpcmciaslot },
-
- { "sysfs", &mapping_addsysfs, &mapping_cmpsysfs, &mapping_getsysfs },
-
- { "prevname", &mapping_addprevname, &mapping_cmpprevname, &mapping_getprevname },
-
- { NULL, NULL, NULL, NULL },
- };
- const int selector_num = sizeof(selector_list)/sizeof(selector_list[0]);
- int selector_active[SELECT_NUM];
- int print_newname = 0;
- char * new_name = NULL;
- int force_takeover = 0;
- int num_takeover = 0;
- int dry_run = 0;
- int verbose = 0;
- int udev_output = 0;
- struct sysfs_metadata sysfs_global =
- {
- NULL, 0,
- 0, { NULL, NULL, NULL, NULL, NULL },
- };
- static int
- if_match_ifname(const char * pattern,
- const char * value)
- {
- const char * p;
- const char * v;
- int n;
- int ret;
-
- p = strchr(pattern, '*');
-
- if(p == NULL)
- return(strcmp(pattern, value));
-
- n = (p - pattern);
- ret = strncmp(pattern, value, n);
- if(ret)
- return(ret);
-
- v = value + n;
- if(!isdigit(*v))
- return(-1);
-
- do
- v++;
- while(isdigit(*v));
-
- p += 1;
-
- return(strcmp(p, v));
- }
- static int
- if_takeover_name(int skfd,
- const char * victimname)
- {
- char autoname[IFNAMSIZ+1];
- int len;
- struct ifreq ifr;
- int ret;
-
- len = strlen(victimname);
- memcpy(autoname, victimname, len + 1);
- if(len > (IFNAMSIZ - 2))
- len = IFNAMSIZ - 2;
- len--;
- while(isdigit(autoname[len]))
- len--;
- strcpy(autoname + len + 1, "%d");
- if(verbose)
- fprintf(stderr, "Takeover : moving interface `%s' to `%s'.\n",
- victimname, autoname);
-
- bzero(&ifr, sizeof(struct ifreq));
- strncpy(ifr.ifr_name, victimname, IFNAMSIZ);
- strncpy(ifr.ifr_newname, autoname, IFNAMSIZ);
-
- ret = ioctl(skfd, SIOCSIFNAME, &ifr);
- if(!ret)
- num_takeover++;
- return(ret);
- }
- static int
- if_set_name(int skfd,
- const char * oldname,
- const char * newname,
- char * retname)
- {
- struct ifreq ifr;
- char * star;
- int ret;
-
- if(!if_match_ifname(newname, oldname))
- {
- if(verbose)
- fprintf(stderr, "Setting : Interface `%s' already matches `%s'.\n",
- oldname, newname);
- strcpy(retname, oldname);
- return(0);
- }
-
- bzero(&ifr, sizeof(struct ifreq));
- strncpy(ifr.ifr_name, oldname, IFNAMSIZ);
- strncpy(ifr.ifr_newname, newname, IFNAMSIZ);
-
- star = strchr(newname, '*');
- if(star != NULL)
- {
- int slen = star - newname;
-
- star = ifr.ifr_newname + slen;
-
- memmove(star + 2, star + 1, IFNAMSIZ - slen - 2);
- star[0] = '%';
- star[1] = 'd';
- }
-
- ret = ioctl(skfd, SIOCSIFNAME, &ifr);
-
- if(ret && (errno == EEXIST) && force_takeover)
- {
-
- ret = if_takeover_name(skfd, newname);
- if(!ret)
-
- ret = ioctl(skfd, SIOCSIFNAME, &ifr);
- }
- if(!ret)
- {
-
- strcpy(retname, ifr.ifr_newname);
- if(verbose)
- fprintf(stderr, "Setting : Interface `%s' renamed to `%s'.\n",
- oldname, retname);
- }
- return(ret);
- }
- static int
- mapping_addmac(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
- size_t n;
-
- extra = extra;
-
- if(len >= sizeof(ifnode->mac_filter))
- {
- fprintf(stderr, "Error : MAC address too long at line %d\n", linenum);
- return(-1);
- }
- n = strspn(string, "0123456789ABCDEFabcdef:*");
- if(n < len)
- {
- fprintf(stderr, "Error: Invalid MAC address `%s' at line %d\n",
- string, linenum);
- return(-1);
- }
-
- memcpy(ifnode->mac_filter, string, len + 1);
-
- if (strchr(ifnode->mac_filter, '*') != NULL)
- {
-
- ifnode->active[SELECT_MAC] = HAS_MAC_FILTER;
- active[SELECT_MAC] = HAS_MAC_FILTER;
- }
- else
- {
-
- ifnode->mac_len = iw_mac_aton(ifnode->mac_filter,
- ifnode->mac, MAX_MAC_LEN);
- if(ifnode->mac_len == 0)
- {
- fprintf(stderr, "Error: Invalid MAC address `%s' at line %d\n",
- ifnode->mac_filter, linenum);
- return(-1);
- }
-
- if((ifnode->mac_len == 6) && (!memcmp(&ifnode->mac, &zero_mac, 6)))
- {
- fprintf(stderr,
- "Warning: MAC address is null at line %d, this is dangerous...\n",
- linenum);
- }
- ifnode->active[SELECT_MAC] = HAS_MAC_EXACT;
- if(active[SELECT_MAC] == 0)
- active[SELECT_MAC] = HAS_MAC_EXACT;
- }
- if(verbose)
- fprintf(stderr,
- "Parsing : Added %s MAC address `%s' from line %d.\n",
- ifnode->active[SELECT_MAC] == HAS_MAC_FILTER ? "filter" : "exact",
- ifnode->mac_filter, linenum);
- return(0);
- }
- static int
- mapping_cmpmac(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- if(ifnode->active[SELECT_MAC] == HAS_MAC_FILTER)
-
- return(fnmatch(ifnode->mac_filter, target->mac_filter, FNM_CASEFOLD));
- else
-
- return((ifnode->mac_len != target->mac_len) ||
- memcmp(ifnode->mac, target->mac, ifnode->mac_len));
- }
- static int
- mapping_getmac(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
- struct ifreq ifr;
- int ret;
- int i;
-
- bzero(&ifr, sizeof(struct ifreq));
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- ret = ioctl(skfd, SIOCGIFHWADDR, &ifr);
- if(ret < 0)
- {
- fprintf(stderr, "Error: Can't read MAC address on interface `%s' : %s\n",
- ifname, strerror(errno));
- return(-1);
- }
-
- target->hw_type = ifr.ifr_hwaddr.sa_family;
-
- target->mac_len = 6;
- for(i = 0; i < weird_mac_len_num; i++)
- if(weird_mac_len[i][0] == ifr.ifr_hwaddr.sa_family)
- {
- target->mac_len = weird_mac_len[i][1];
- break;
- }
-
- memcpy(target->mac, ifr.ifr_hwaddr.sa_data, target->mac_len);
-
- if((flag == HAS_MAC_FILTER) || verbose)
- {
-
- iw_mac_ntop(target->mac, target->mac_len,
- target->mac_filter, sizeof(target->mac_filter));
- }
- target->active[SELECT_MAC] = flag;
- target->active[SELECT_ARP] = 1;
- if(verbose)
- fprintf(stderr,
- "Querying %s : Got MAC address `%s' and ARP/Link Type `%d'.\n",
- ifname, target->mac_filter, target->hw_type);
- return(0);
- }
- static int
- mapping_addarp(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
- size_t n;
- unsigned int type;
-
- extra = extra;
-
- n = strspn(string, "0123456789");
- if((n < len) || (sscanf(string, "%d", &type) != 1))
- {
- fprintf(stderr, "Error: Invalid ARP/Link Type `%s' at line %d\n",
- string, linenum);
- return(-1);
- }
- ifnode->hw_type = (unsigned short) type;
- ifnode->active[SELECT_ARP] = 1;
- active[SELECT_ARP] = 1;
- if(verbose)
- fprintf(stderr, "Parsing : Added ARP/Link Type `%d' from line %d.\n",
- ifnode->hw_type, linenum);
- return(0);
- }
- static int
- mapping_cmparp(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
- return(!(ifnode->hw_type == target->hw_type));
- }
- static int
- mapping_getarp(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
-
- if(target->active[SELECT_MAC])
- return(0);
-
- return(mapping_getmac(skfd, ifname, target, flag));
- }
- static int
- mapping_adddriver(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
-
- extra = extra;
-
- if(len >= sizeof(ifnode->driver))
- {
- fprintf(stderr, "Error: Driver name too long at line %d\n", linenum);
- return(-1);
- }
-
- memcpy(ifnode->driver, string, len + 1);
-
- ifnode->active[SELECT_DRIVER] = 1;
- active[SELECT_DRIVER] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added Driver name `%s' from line %d.\n",
- ifnode->driver, linenum);
- return(0);
- }
- static int
- mapping_cmpdriver(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- return(fnmatch(ifnode->driver, target->driver, FNM_CASEFOLD));
- }
- static int
- mapping_addbusinfo(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
- #if 0
- size_t n;
- #endif
-
- extra = extra;
-
- if(len >= sizeof(ifnode->bus_info))
- {
- fprintf(stderr, "Bus Info too long at line %d\n", linenum);
- return(-1);
- }
- #if 0
-
- n = strspn(string, "0123456789ABCDEFabcdef:.*");
- if(n < len)
- {
- fprintf(stderr, "Error: Invalid Bus Info `%s' at line %d\n",
- string, linenum);
- return(-1);
- }
- #endif
-
- memcpy(ifnode->bus_info, string, len + 1);
-
- ifnode->active[SELECT_BUSINFO] = 1;
- active[SELECT_BUSINFO] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added Bus Info `%s' from line %d.\n",
- ifnode->bus_info, linenum);
- return(0);
- }
- static int
- mapping_cmpbusinfo(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- return(fnmatch(ifnode->bus_info, target->bus_info, FNM_CASEFOLD));
- }
- static int
- mapping_addfirmware(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
-
- extra = extra;
-
- if(len >= sizeof(ifnode->fw_version))
- {
- fprintf(stderr, "Firmware revision too long at line %d\n", linenum);
- return(-1);
- }
-
- memcpy(ifnode->fw_version, string, len + 1);
-
- ifnode->active[SELECT_FIRMWARE] = 1;
- active[SELECT_FIRMWARE] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added Firmware Revision `%s' from line %d.\n",
- ifnode->fw_version, linenum);
- return(0);
- }
- static int
- mapping_cmpfirmware(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- return(fnmatch(ifnode->fw_version, target->fw_version, FNM_CASEFOLD));
- }
- static int
- mapping_getdriverbusinfo(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
- struct ifreq ifr;
- struct ethtool_drvinfo drvinfo;
- int ret;
-
- flag = flag;
-
- if(target->active[SELECT_DRIVER] || target->active[SELECT_BUSINFO]
- || target->active[SELECT_FIRMWARE])
- return(0);
-
- bzero(&ifr, sizeof(struct ifreq));
- bzero(&drvinfo, sizeof(struct ethtool_drvinfo));
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr.ifr_data = (caddr_t) &drvinfo;
-
- ret = ioctl(skfd, SIOCETHTOOL, &ifr);
- if(ret < 0)
- {
-
- if(verbose)
- fprintf(stderr,
- "Error: Can't read driver/bus-info on interface `%s' : %s\n",
- ifname, strerror(errno));
- return(-1);
- }
-
- strcpy(target->driver, drvinfo.driver);
- strcpy(target->bus_info, drvinfo.bus_info);
- strcpy(target->fw_version, drvinfo.fw_version);
-
- target->active[SELECT_DRIVER] = 1;
- target->active[SELECT_BUSINFO] = 1;
- target->active[SELECT_FIRMWARE] = 1;
- if(verbose)
- fprintf(stderr,
- "Querying %s : Got Driver name `%s', Bus Info `%s' and Firmware `%s'.\n",
- ifname, target->driver, target->bus_info, target->fw_version);
- return(0);
- }
- static int
- mapping_addbaseaddr(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
- size_t n;
- unsigned int address;
-
- extra = extra;
-
- n = strspn(string, "0123456789ABCDEFabcdefx");
- if((n < len) || (sscanf(string, "0x%X", &address) != 1))
- {
- fprintf(stderr, "Error: Invalid Base Address `%s' at line %d\n",
- string, linenum);
- return(-1);
- }
-
- ifnode->base_addr = (unsigned short) address;
-
- ifnode->active[SELECT_BASEADDR] = 1;
- active[SELECT_BASEADDR] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added Base Address `0x%X' from line %d.\n",
- ifnode->base_addr, linenum);
- return(0);
- }
- static int
- mapping_cmpbaseaddr(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- return(!(ifnode->base_addr == target->base_addr));
- }
- static int
- mapping_addirq(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
- size_t n;
- unsigned int irq;
-
- extra = extra;
-
- n = strspn(string, "0123456789");
- if((n < len) || (sscanf(string, "%d", &irq) != 1))
- {
- fprintf(stderr, "Error: Invalid Base Address `%s' at line %d\n",
- string, linenum);
- return(-1);
- }
-
- ifnode->irq = (unsigned char) irq;
-
- ifnode->active[SELECT_IRQ] = 1;
- active[SELECT_IRQ] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added IRQ `%d' from line %d.\n",
- ifnode->irq, linenum);
- return(0);
- }
- static int
- mapping_cmpirq(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- return(!(ifnode->irq == target->irq));
- }
- static int
- mapping_getbaseaddrirq(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
- struct ifreq ifr;
- struct ifmap map;
- int ret;
-
- flag = flag;
-
- if(target->active[SELECT_BASEADDR] || target->active[SELECT_IRQ])
- return(0);
-
- bzero(&ifr, sizeof(struct ifreq));
- bzero(&map, sizeof(struct ifmap));
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-
- ret = ioctl(skfd, SIOCGIFMAP, &ifr);
- if(ret < 0)
- {
-
- if(verbose)
- fprintf(stderr,
- "Error: Can't read base address/irq on interface `%s' : %s\n",
- ifname, strerror(errno));
- return(-1);
- }
-
- if(ifr.ifr_map.base_addr >= 0x100)
- {
- target->base_addr = ifr.ifr_map.base_addr;
- target->active[SELECT_BASEADDR] = 1;
- }
- target->irq = ifr.ifr_map.irq;
- target->active[SELECT_IRQ] = 1;
- if(verbose)
- fprintf(stderr,
- "Querying %s : Got Base Address `0x%X' and IRQ `%d'.\n",
- ifname, target->base_addr, target->irq);
- return(0);
- }
- static int
- mapping_addiwproto(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
-
- extra = extra;
-
- if(len >= sizeof(ifnode->iwproto))
- {
- fprintf(stderr, "Wireless Protocol too long at line %d\n", linenum);
- return(-1);
- }
-
- memcpy(ifnode->iwproto, string, len + 1);
-
- ifnode->active[SELECT_IWPROTO] = 1;
- active[SELECT_IWPROTO] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added Wireless Protocol `%s' from line %d.\n",
- ifnode->iwproto, linenum);
- return(0);
- }
- static int
- mapping_cmpiwproto(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- return(fnmatch(ifnode->iwproto, target->iwproto, FNM_CASEFOLD));
- }
- static int
- mapping_getiwproto(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
- struct iwreq wrq;
-
- flag = flag;
-
- if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
-
- return(-1);
- strncpy(target->iwproto, wrq.u.name, IFNAMSIZ);
- target->iwproto[IFNAMSIZ] = '\0';
-
- target->active[SELECT_IWPROTO] = 1;
- if(verbose)
- fprintf(stderr,
- "Querying %s : Got Wireless Protocol `%s'.\n",
- ifname, target->iwproto);
- return(0);
- }
- static int
- mapping_addpcmciaslot(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
- size_t n;
-
- extra = extra;
-
- n = strspn(string, "0123456789");
- if((n < len) || (sscanf(string, "%d", &ifnode->pcmcia_slot) != 1))
- {
- fprintf(stderr, "Error: Invalid Pcmcia Slot `%s' at line %d\n",
- string, linenum);
- return(-1);
- }
- ifnode->active[SELECT_PCMCIASLOT] = 1;
- active[SELECT_PCMCIASLOT] = 1;
- if(verbose)
- fprintf(stderr, "Parsing : Added Pcmcia Slot `%d' from line %d.\n",
- ifnode->pcmcia_slot, linenum);
- return(0);
- }
- static int
- mapping_cmppcmciaslot(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
- return(!(ifnode->pcmcia_slot == target->pcmcia_slot));
- }
- static int
- mapping_getpcmciaslot(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
- FILE * stream;
- char * linebuf = NULL;
- size_t linelen = 0;
- int linenum = 0;
-
- skfd = skfd;
- flag = flag;
-
- stream = fopen(PCMCIA_STAB1, "r");
- if(!stream)
- {
-
- stream = fopen(PCMCIA_STAB2, "r");
- if(!stream)
- {
- fprintf(stderr, "Error: Can't open PCMCIA Stab file `%s' or `%s': %s\n",
- PCMCIA_STAB1, PCMCIA_STAB2, strerror(errno));
- return(-1);
- }
- }
-
- while(getline(&linebuf, &linelen, stream) > 0)
- {
- char * p;
- size_t n;
- size_t k;
- int pcmcia_slot;
- int i;
-
- linenum++;
-
- p = linebuf;
- while(isspace(*p))
- ++p;
- if(*p == '\0')
- continue;
- n = strcspn(p, " \t\n");
- k = strspn(p, "0123456789");
- if((k < n) || (sscanf(p, "%d", &pcmcia_slot) != 1))
-
- continue;
-
-
- for(i = 0; i < 4; i++)
- {
-
- p += n;
-
- p += strspn(p, " \t\n");
- if(*p == '\0')
- break;
-
- n = strcspn(p, " \t\n");
- }
- if(*p == '\0')
- continue;
-
- p[n] = '\0';
-
- if(!strcmp(p, ifname))
- {
-
- target->pcmcia_slot = pcmcia_slot;
-
- target->active[SELECT_PCMCIASLOT] = 1;
- if(verbose)
- fprintf(stderr,
- "Querying %s : Got Pcmcia Slot `%d'.\n",
- ifname, target->pcmcia_slot);
-
- break;
- }
-
- }
-
- free(linebuf);
- fclose(stream);
- return(target->active[SELECT_PCMCIASLOT] ? 0 : -1);
- }
- static int
- mapping_addsysfs(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
- int findex;
- char * sdup;
-
- if((extra == NULL) || (extra->modif_pos == NULL))
- {
- fprintf(stderr, "Error: No SYSFS filename at line %d\n", linenum);
- return(-1);
- }
-
- for(findex = 0; findex < sysfs_global.filenum; findex++)
- {
- if(!strcmp(extra->modif_pos, sysfs_global.filename[findex]))
- break;
- }
-
- if(findex == sysfs_global.filenum)
- {
- if(findex == SYSFS_MAX_FILE)
- {
- fprintf(stderr, "Error: Too many SYSFS filenames at line %d\n", linenum);
- return(-1);
- }
- sdup = strndup(extra->modif_pos, extra->modif_len);
- if(sdup == NULL)
- {
- fprintf(stderr, "Error: Can't allocate SYSFS file\n");
- return(-1);
- }
- sysfs_global.filename[findex] = sdup;
- sysfs_global.filenum++;
- }
-
- sdup = strndup(string, len);
- if(sdup == NULL)
- {
- fprintf(stderr, "Error: Can't allocate SYSFS value\n");
- return(-1);
- }
- ifnode->sysfs[findex] = sdup;
-
- ifnode->active[SELECT_SYSFS] = 1;
- active[SELECT_SYSFS] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added SYSFS filename `%s' value `%s' from line %d.\n",
- sysfs_global.filename[findex], ifnode->sysfs[findex], linenum);
- return(0);
- }
- static int
- mapping_cmpsysfs(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
- int findex;
- int match = 1;
-
- for(findex = 0; findex < sysfs_global.filenum; findex++)
- {
-
- if(ifnode->sysfs[findex] != NULL)
-
- if((target->sysfs[findex] == NULL) ||
- (fnmatch(ifnode->sysfs[findex], target->sysfs[findex],
- FNM_CASEFOLD)))
-
- match = 0;
- }
- return(!match);
- }
- static int
- mapping_getsysfs(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
- FILE * stream;
- char * fname;
- int fnsize;
- char * linebuf = NULL;
- size_t linelen = 0;
- char * sdup;
- int findex;
-
- skfd = skfd;
- flag = flag;
-
- if(target->sysfs_devpath == NULL)
- {
-
- if(sysfs_global.root == NULL)
- {
-
- stream = fopen("/proc/mounts", "r");
- if(!stream)
- {
- fprintf(stderr, "Error: Can't open /proc/mounts file: %s\n",
- strerror(errno));
- return(-1);
- }
-
- while(getline(&linebuf, &linelen, stream) > 0)
- {
- int i;
- char * p;
- size_t n;
- char * token[3];
- size_t toklen[3];
-
-
- p = linebuf;
- for(i = 0; i < 3; i++)
- {
- while(isspace(*p))
- ++p;
- token[i] = p;
- n = strcspn(p, " \t\n");
- toklen[i] = n;
- p += n;
- }
-
- if((n == 5) && (!strncasecmp(token[2], "sysfs", 5)))
- {
-
- n = toklen[1];
- sdup = strndup(token[1], n);
- if((n == 0) || (sdup == NULL))
- {
- fprintf(stderr,
- "Error: Can't parse /proc/mounts file: %s\n",
- strerror(errno));
- return(-1);
- }
-
- sysfs_global.root = sdup;
- sysfs_global.rlen = n;
- break;
- }
-
- }
-
- fclose(stream);
-
- if(sysfs_global.root == NULL)
- {
- fprintf(stderr,
- "Error: Can't find sysfs in /proc/mounts file\n");
- free(linebuf);
- return(-1);
- }
- }
-
- fnsize = (sysfs_global.rlen + 11 + IFNAMSIZ + 1);
- fname = malloc(fnsize);
- if(fname == NULL)
- {
- fprintf(stderr, "Error: Can't allocate SYSFS devpath\n");
- return(-1);
- }
-
- target->sysfs_devplen = sprintf(fname, "%s/class/net/%s",
- sysfs_global.root, ifname);
- target->sysfs_devpath = fname;
- }
-
- for(findex = 0; findex < sysfs_global.filenum; findex++)
- {
- char * p;
- ssize_t n;
-
- fnsize = (target->sysfs_devplen + 1 +
- strlen(sysfs_global.filename[findex]) + 1);
- fname = malloc(fnsize);
- if(fname == NULL)
- {
- fprintf(stderr, "Error: Can't allocate SYSFS filename\n");
- free(linebuf);
- return(-1);
- }
- sprintf(fname, "%s/%s", target->sysfs_devpath,
- sysfs_global.filename[findex]);
-
- stream = fopen(fname, "r");
- if(!stream)
- {
-
- if(verbose)
- fprintf(stderr, "Error: Can't open file `%s': %s\n", fname,
- strerror(errno));
-
- continue;
- }
-
- n = getline(&linebuf, &linelen, stream);
- fclose(stream);
- if(n <= 0)
- {
-
-
- int allocsize = 128;
- int retry = 16;
- char * linkpath = NULL;
- int pathlen;
-
- do
- {
- allocsize *= 2;
- linkpath = realloc(linkpath, allocsize);
- pathlen = readlink(fname, linkpath, allocsize);
-
- if(pathlen < allocsize)
- break;
- }
- while(retry-- > 0);
-
- if(pathlen > 0)
-
- linkpath[pathlen] = '\0';
- else
- {
-
- free(linkpath);
-
-
- if(!strcmp(fname + fnsize - 4, "/.."))
-
- {
-
- int cwd_fd = open(".", O_RDONLY);
- linkpath = NULL;
- if(cwd_fd > 0)
- {
- int ret = chdir(fname);
- if(ret == 0)
-
- linkpath = getcwd(NULL, 0);
-
- fchdir(cwd_fd);
- }
-
- if(!linkpath)
- {
- free(linkpath);
- if(verbose)
- fprintf(stderr, "Error: Can't read parent directory `%s'\n", fname);
-
- continue;
- }
- }
- else
- {
-
- if(verbose)
- fprintf(stderr, "Error: Can't read file `%s'\n", fname);
-
- continue;
- }
- }
-
-
- p = basename(linkpath);
- sdup = strdup(p);
- free(linkpath);
- }
- else
- {
-
-
- p = linebuf;
- if(p[n - 1] == '\n')
- n--;
- sdup = strndup(p, n);
- }
- if(sdup == NULL)
- {
- fprintf(stderr, "Error: Can't allocate SYSFS value\n");
- free(linebuf);
- return(-1);
- }
- target->sysfs[findex] = sdup;
-
- target->active[SELECT_SYSFS] = 1;
- if(verbose)
- fprintf(stderr,
- "Querying %s : Got SYSFS filename `%s' value `%s'.\n",
- ifname, sysfs_global.filename[findex], target->sysfs[findex]);
-
- }
-
- free(linebuf);
- return(target->active[SELECT_SYSFS] ? 0 : -1);
- }
- static int
- mapping_addprevname(struct if_mapping * ifnode,
- int * active,
- char * string,
- size_t len,
- struct add_extra * extra,
- int linenum)
- {
-
- extra = extra;
-
- if(len >= sizeof(ifnode->prevname))
- {
- fprintf(stderr, "Old Interface Name too long at line %d\n", linenum);
- return(-1);
- }
-
- memcpy(ifnode->prevname, string, len + 1);
-
- ifnode->active[SELECT_PREVNAME] = 1;
- active[SELECT_PREVNAME] = 1;
- if(verbose)
- fprintf(stderr,
- "Parsing : Added Old Interface Name `%s' from line %d.\n",
- ifnode->prevname, linenum);
- return(0);
- }
- static int
- mapping_cmpprevname(struct if_mapping * ifnode,
- struct if_mapping * target)
- {
-
- return(fnmatch(ifnode->prevname, target->ifname, FNM_CASEFOLD));
- }
- static int
- mapping_getprevname(int skfd,
- const char * ifname,
- struct if_mapping * target,
- int flag)
- {
-
- skfd = skfd; ifname = ifname; flag = flag;
-
-
- target->active[SELECT_PREVNAME] = 1;
- return(0);
- }
- static struct if_mapping *
- mapping_create(char * pos,
- int len,
- int linenum)
- {
- struct if_mapping * ifnode;
- char * star;
- star = memchr(pos, '*', len);
-
- if((len + (star != NULL)) > IFNAMSIZ)
- {
- fprintf(stderr, "Error: Interface name `%.*s' too long at line %d\n",
- (int) len, pos, linenum);
- return(NULL);
- }
-
- ifnode = calloc(1, sizeof(if_mapping));
- if(!ifnode)
- {
- fprintf(stderr, "Error: Can't allocate interface mapping.\n");
- return(NULL);
- }
-
- memcpy(ifnode->ifname, pos, len);
- ifnode->ifname[len] = '\0';
-
- if((!force_takeover) &&
- ((!strcmp(ifnode->ifname, "eth0")) || (!strcmp(ifnode->ifname, "wlan0"))))
- fprintf(stderr,
- "Warning: Interface name is `%s' at line %d, can't be mapped reliably.\n",
- ifnode->ifname, linenum);
- if(strchr(ifnode->ifname, ':'))
- fprintf(stderr, "Warning: Alias device `%s' at line %d probably can't be mapped.\n",
- ifnode->ifname, linenum);
- if(verbose)
- fprintf(stderr, "Parsing : Added Mapping `%s' from line %d.\n",
- ifnode->ifname, linenum);
-
- return(ifnode);
- }
- static inline const struct mapping_selector *
- selector_find(const char * string,
- size_t slen,
- int linenum)
- {
- const struct mapping_selector * found = NULL;
- int ambig = 0;
- int i;
-
- for(i = 0; selector_list[i].name != NULL; ++i)
- {
-
- if(strncasecmp(selector_list[i].name, string, slen) != 0)
- continue;
-
- if(slen == strlen(selector_list[i].name))
- return &selector_list[i];
-
- if(found == NULL)
-
- found = &selector_list[i];
- else
-
- if (selector_list[i].add_fn != found->add_fn)
- ambig = 1;
- }
- if(found == NULL)
- {
- fprintf(stderr, "Error: Unknown selector `%.*s' at line %d.\n",
- (int) slen, string, linenum);
- return NULL;
- }
- if(ambig)
- {
- fprintf(stderr, "Selector `%.*s'at line %d is ambiguous.\n",
- (int) slen, string, linenum);
- return NULL;
- }
- return found;
- }
- static int
- mapping_readfile(const char * filename)
- {
- FILE * stream;
- char * linebuf = NULL;
- size_t linelen = 0;
- int linenum = 0;
- struct add_extra extrainfo;
-
- bzero(selector_active, sizeof(selector_active));
-
- if(!strcmp(filename, "-"))
- {
-
- stream = stdin;
- }
- else
- {
-
- stream = fopen(filename, "r");
- if(!stream)
- {
- fprintf(stderr, "Error: Can't open configuration file `%s': %s\n",
- filename, strerror(errno));
- return(-1);
- }
- }
-
- while(getline(&linebuf, &linelen, stream) > 0)
- {
- struct if_mapping * ifnode;
- char * p;
- char * e;
- size_t n;
- int ret = -13;
-
- linenum++;
-
- if((p = strchr(linebuf,'#')) != NULL)
- *p = '\0';
-
- p = linebuf;
- while(isspace(*p))
- ++p;
- if(*p == '\0')
- continue;
- n = strcspn(p, " \t\n");
-
- ifnode = mapping_create(p, n, linenum);
- if(!ifnode)
- continue;
- p += n;
- p += strspn(p, " \t\n");
-
- while(*p != '\0')
- {
- const struct mapping_selector * selector = NULL;
- struct add_extra * extra = NULL;
-
- n = strcspn(p, " \t\n{");
-
- selector = selector_find(p, n, linenum);
- if(!selector)
- {
- ret = -1;
- break;
- }
- p += n;
-
- if(*p == '{')
- {
- p++;
-
- e = strchr(p, '}');
- if(e == NULL)
- {
- fprintf(stderr,
- "Error: unterminated selector modifier value on line %d\n",
- linenum);
- ret = -1;
- break;
- }
-
- extrainfo.modif_pos = p;
- extrainfo.modif_len = e - p;
- extra = &extrainfo;
-
- e[0] = '\0';
-
- p = e + 1;
- }
-
- p += strspn(p, " \t\n");
- if(*p == '\0')
- {
- fprintf(stderr, "Error: no value for selector `%s' on line %d\n",
- selector->name, linenum);
- ret = -1;
- break;
- }
-
- if(*p == '"')
- {
- p++;
- e = strchr(p, '"');
- if(e == NULL)
- {
- fprintf(stderr,
- "Error: unterminated quoted value on line %d\n",
- linenum);
- ret = -1;
- break;
- }
- n = e - p;
- e++;
- }
- else
- {
-
- n = strcspn(p, " \t\n");
- e = p + n;
- }
-
- if(*e != '\0')
- e++;
-
- p[n] = '\0';
-
- ret = selector->add_fn(ifnode, selector_active, p, n,
- extra, linenum);
- if(ret < 0)
- break;
-
- p = e;
- p += strspn(p, " \t\n");
- }
-
- if(ret < 0)
- {
-
- if(ret == -13)
- fprintf(stderr, "Error: Line %d ignored, no valid selectors\n",
- linenum);
- else
- fprintf(stderr, "Error: Line %d ignored due to prior errors\n",
- linenum);
- free(ifnode);
- }
- else
- {
-
- ifnode->next = mapping_list;
- mapping_list = ifnode;
- }
- }
-
- free(linebuf);
-
- if(stream != stdin)
- fclose(stream);
- return(0);
- }
- static struct if_mapping *
- mapping_extract(int skfd,
- const char * ifname)
- {
- struct if_mapping * target;
- int i;
-
- target = calloc(1, sizeof(if_mapping));
- if(!target)
- {
- fprintf(stderr, "Error: Can't allocate interface mapping.\n");
- return(NULL);
- }
-
- strcpy(target->ifname, ifname);
-
- for(i = 0; i < SELECT_NUM; i++)
- {
-
- if(selector_active[i] != 0)
- {
-
- selector_list[i].get_fn(skfd, ifname, target, selector_active[i]);
-
- }
- }
- return(target);
- }
- static struct if_mapping *
- mapping_find(struct if_mapping * target)
- {
- struct if_mapping * ifnode;
- int i;
-
- for(ifnode = mapping_list; ifnode != NULL; ifnode = ifnode->next)
- {
- int matches = 1;
-
- for(i = 0; i < SELECT_NUM; i++)
- {
-
- if(ifnode->active[i] != 0)
- {
-
- if((target->active[i] == 0) ||
- (selector_list[i].cmp_fn(ifnode, target) != 0))
- {
- matches = 0;
- break;
- }
- }
- }
-
- if(matches)
- return(ifnode);
- }
-
- return(NULL);
- }
- static void
- probe_mappings(int skfd)
- {
- struct if_mapping * ifnode;
- struct ifreq ifr;
-
- for(ifnode = mapping_list; ifnode != NULL; ifnode = ifnode->next)
- {
-
- if(strchr(ifnode->ifname, '%') != NULL)
- continue;
- if(verbose)
- fprintf(stderr, "Probing : Trying to load interface [%s]\n",
- ifnode->ifname);
-
- strncpy(ifr.ifr_name, ifnode->ifname, IFNAMSIZ);
- ioctl(skfd, SIOCGIFHWADDR, &ifr);
- }
- }
- static void
- probe_debian(int skfd)
- {
- FILE * stream;
- char * linebuf = NULL;
- size_t linelen = 0;
- struct ifreq ifr;
-
- stream = fopen(DEBIAN_CONFIG_FILE, "r");
- if(stream == NULL)
- {
- fprintf(stderr, "Error: can't open file [%s]\n", DEBIAN_CONFIG_FILE);
- return;
- }
-
- while(getline(&linebuf, &linelen, stream) > 0)
- {
- char * p;
- char * e;
- size_t n;
-
- if(!strncasecmp(linebuf, "auto ", 5))
- {
-
- p = linebuf + 5;
-
- e = strchr(p, '#');
- if(e != NULL)
- *e = '\0';
-
- while(*p != '\0')
- {
-
- n = strcspn(p, " \t\n");
-
- e = p + n;
-
- if(*e != '\0')
- e++;
-
- p[n] = '\0';
- if(verbose)
- fprintf(stderr, "Probing : Trying to load interface [%s]\n",
- p);
-
- strncpy(ifr.ifr_name, p, IFNAMSIZ);
- ioctl(skfd, SIOCGIFHWADDR, &ifr);
-
- p = e;
- p += strspn(p, " \t\n");
- }
- }
- }
-
- fclose(stream);
- return;
- }
- static int
- process_rename(int skfd,
- char * ifname,
- char * newname)
- {
- char retname[IFNAMSIZ+1];
- int len;
- char * star;
- len = strlen(newname);
- star = strchr(newname, '*');
-
- if((len + (star != NULL)) > IFNAMSIZ)
- {
- fprintf(stderr, "Error: Interface name `%s' too long.\n",
- newname);
- return(-1);
- }
-
- if(if_set_name(skfd, ifname, newname, retname) < 0)
- {
- fprintf(stderr, "Error: cannot change name of %s to %s: %s\n",
- ifname, newname, strerror(errno));
- return(-1);
- }
-
- printf("%s\n", retname);
-
- return(0);
- }
- static int
- process_ifname(int skfd,
- char * ifname,
- char * args[],
- int count)
- {
- struct if_mapping * target;
- const struct if_mapping * mapping;
- char retname[IFNAMSIZ+1];
-
- args = args; count = count;
-
- target = mapping_extract(skfd, ifname);
- if(target == NULL)
- return(-1);
-
- if(udev_output)
- {
- const char *env;
-
- env = getenv("DEVPATH");
- if(env)
- {
- int env_len = strlen(env);
- target->sysfs_devplen = env_len;
-
- target->sysfs_devpath = malloc(env_len + IFNAMSIZ + 1);
- if(target->sysfs_devpath != NULL)
- memcpy(target->sysfs_devpath, env, env_len + 1);
- }
-
- }
-
- mapping = mapping_find(target);
- if(mapping == NULL)
- return(-1);
-
- if((new_name != NULL) && (if_match_ifname(mapping->ifname, new_name) != 0))
- return(-1);
-
- if(dry_run)
- {
- strcpy(retname, mapping->ifname);
- fprintf(stderr, "Dry-run : Would rename %s to %s.\n",
- target->ifname, mapping->ifname);
- }
- else
- {
-
- if(if_set_name(skfd, target->ifname, mapping->ifname, retname) < 0)
- {
- fprintf(stderr, "Error: cannot change name of %s to %s: %s\n",
- target->ifname, mapping->ifname, strerror(errno));
- return(-1);
- }
- }
-
- if(print_newname)
- {
- if(!udev_output)
-
- printf("%s\n", retname);
- else
-
- if(strcmp(target->ifname, retname))
- {
- char * pos;
-
- if(!target->sysfs_devpath)
- mapping_getsysfs(skfd, ifname, target, 0);
-
- pos = strrchr(target->sysfs_devpath, '/');
- if((pos != NULL) && (!strcmp(target->ifname, pos + 1)))
- strcpy(pos + 1, retname);
-
- printf("DEVPATH=%s\nINTERFACE=%s\nINTERFACE_OLD=%s\n",
- target->sysfs_devpath, retname, target->ifname);
- }
- }
-
- return(0);
- }
- static inline int
- process_iflist(int skfd,
- char * args[],
- int count)
- {
- num_takeover = 0;
-
- iw_enum_devices(skfd, &process_ifname, args, count);
-
- if(force_takeover && num_takeover)
-
- iw_enum_devices(skfd, &process_ifname, args, count);
-
- return(0);
- }
- static void
- usage(void)
- {
- fprintf(stderr, "usage: ifrename [-c configurationfile] [-i ifname] [-p] [-t] [-d] [-D]\n");
- exit(1);
- }
- int
- main(int argc,
- char * argv[])
- {
- const char * conf_file = DEFAULT_CONF;
- char * ifname = NULL;
- int use_probe = 0;
- int is_debian = 0;
- int skfd;
- int ret;
-
- while(1)
- {
- int c = getopt_long(argc, argv, "c:dDi:n:ptuvV", long_opt, NULL);
- if(c == -1)
- break;
- switch(c)
- {
- default:
- case '?':
- usage();
- case 'c':
- conf_file = optarg;
- break;
- case 'd':
- is_debian = 1;
- break;
- case 'D':
- dry_run = 1;
- break;
- case 'i':
- ifname = optarg;
- break;
- case 'n':
- new_name = optarg;
- break;
- case 'p':
- use_probe = 1;
- break;
- case 't':
- force_takeover = 1;
- break;
- case 'u':
- udev_output = 1;
- break;
- case 'v':
- printf("%-8.16s Wireless-Tools version %d\n", "ifrename", WT_VERSION);
- return(0);
- case 'V':
- verbose = 1;
- break;
- }
- }
-
- if(mapping_readfile(conf_file) < 0)
- return(-1);
-
- if((skfd = iw_sockets_open()) < 0)
- {
- perror("socket");
- return(-1);
- }
-
- if(ifname != NULL)
- {
-
- if(new_name != NULL)
- {
-
- ret = process_rename(skfd, ifname, new_name);
- }
- else
- {
-
- print_newname = 1;
- ret = process_ifname(skfd, ifname, NULL, 0);
- }
- }
- else
- {
-
- if(use_probe)
- {
- if(is_debian)
- probe_debian(skfd);
- else
- probe_mappings(skfd);
- }
-
- ret = process_iflist(skfd, NULL, 0);
- }
-
- iw_sockets_close(skfd);
- return(ret);
- }
|