Add the ability to match the on a media type of the device in question.
Submitted by: sam Approved by: re (scottl)
This commit is contained in:
parent
983982e20a
commit
68644ee7c2
@ -190,6 +190,71 @@ match::do_match(config &c)
|
||||
return retval;
|
||||
}
|
||||
|
||||
#include <sys/sockio.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
media::media(config &c, const char *var, const char *type)
|
||||
: _var(var), _type(-1)
|
||||
{
|
||||
static struct ifmedia_description media_types[] = {
|
||||
{ IFM_ETHER, "Ethernet" },
|
||||
{ IFM_TOKEN, "Tokenring" },
|
||||
{ IFM_FDDI, "FDDI" },
|
||||
{ IFM_IEEE80211, "802.11" },
|
||||
{ IFM_ATM, "ATM" },
|
||||
{ IFM_CARP, "CARP" },
|
||||
{ -1, "unknown" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
for (int i = 0; media_types[i].ifmt_string != NULL; i++)
|
||||
if (strcasecmp(type, media_types[i].ifmt_string) == 0) {
|
||||
_type = media_types[i].ifmt_word;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
media::~media()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
media::do_match(config &c)
|
||||
{
|
||||
string value = c.get_variable("device-name");
|
||||
struct ifmediareq ifmr;
|
||||
bool retval;
|
||||
int s;
|
||||
|
||||
if (Dflag)
|
||||
fprintf(stderr, "Testing media type of %s against 0x%x\n",
|
||||
value.c_str(), _type);
|
||||
|
||||
retval = false;
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strncpy(ifmr.ifm_name, value.c_str(), sizeof(ifmr.ifm_name));
|
||||
|
||||
if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0 &&
|
||||
ifmr.ifm_status & IFM_AVALID) {
|
||||
if (Dflag)
|
||||
fprintf(stderr, "%s has media type 0x%x\n",
|
||||
value.c_str(), IFM_TYPE(ifmr.ifm_active));
|
||||
retval = (IFM_TYPE(ifmr.ifm_active) == _type);
|
||||
} else if (_type == -1) {
|
||||
if (Dflag)
|
||||
fprintf(stderr, "%s has unknown media type\n",
|
||||
value.c_str());
|
||||
retval = true;
|
||||
}
|
||||
close(s);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
const string var_list::bogus = "_$_$_$_$_B_O_G_U_S_$_$_$_$_";
|
||||
const string var_list::nothing = "";
|
||||
|
||||
@ -772,6 +837,15 @@ new_match(const char *var, const char *re)
|
||||
return (e);
|
||||
}
|
||||
|
||||
eps *
|
||||
new_media(const char *var, const char *re)
|
||||
{
|
||||
eps *e = new media(cfg, var, re);
|
||||
free(const_cast<char *>(var));
|
||||
free(const_cast<char *>(re));
|
||||
return (e);
|
||||
}
|
||||
|
||||
void
|
||||
set_pidfile(const char *name)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ void add_nomatch(int, struct event_proc *);
|
||||
void add_notify(int, struct event_proc *);
|
||||
struct event_proc *add_to_event_proc(struct event_proc *, struct eps *);
|
||||
struct eps *new_match(const char *, const char *);
|
||||
struct eps *new_media(const char *, const char *);
|
||||
struct eps *new_action(const char *);
|
||||
void set_pidfile(const char *);
|
||||
void set_variable(const char *, const char *);
|
||||
|
@ -95,6 +95,22 @@ private:
|
||||
regex_t _regex;
|
||||
};
|
||||
|
||||
/**
|
||||
* media is the subclass used to match an individual variable. Its
|
||||
* actions are nops.
|
||||
*/
|
||||
class media : public eps
|
||||
{
|
||||
public:
|
||||
media(config &, const char *var, const char *type);
|
||||
virtual ~media();
|
||||
virtual bool do_match(config &);
|
||||
virtual bool do_action(config &) { return true; }
|
||||
private:
|
||||
std::string _var;
|
||||
int _type;
|
||||
};
|
||||
|
||||
/**
|
||||
* action is used to fork a process. It matches everything.
|
||||
*/
|
||||
|
@ -47,7 +47,7 @@
|
||||
%token <str> STRING
|
||||
%token <str> ID
|
||||
%token OPTIONS SET DIRECTORY PID_FILE DEVICE_NAME ACTION MATCH
|
||||
%token ATTACH DETACH NOMATCH NOTIFY
|
||||
%token ATTACH DETACH NOMATCH NOTIFY MEDIA_TYPE CLASS SUBDEVICE
|
||||
|
||||
%type <eventproc> match_or_action_list
|
||||
%type <eps> match_or_action match action
|
||||
@ -137,6 +137,12 @@ match
|
||||
: MATCH STRING STRING SEMICOLON { $$ = new_match($2, $3); }
|
||||
| DEVICE_NAME STRING SEMICOLON
|
||||
{ $$ = new_match(strdup("device-name"), $2); }
|
||||
| MEDIA_TYPE STRING SEMICOLON
|
||||
{ $$ = new_media(strdup("media-type"), $2); }
|
||||
| CLASS STRING SEMICOLON
|
||||
{ $$ = new_match(strdup("class"), $2); }
|
||||
| SUBDEVICE STRING SEMICOLON
|
||||
{ $$ = new_match(strdup("subdevice"), $2); }
|
||||
;
|
||||
|
||||
action
|
||||
|
@ -90,6 +90,9 @@ pid-file { return PID_FILE; }
|
||||
attach { return ATTACH; }
|
||||
detach { return DETACH; }
|
||||
device-name { return DEVICE_NAME; }
|
||||
media-type { return MEDIA_TYPE; }
|
||||
class { return CLASS; }
|
||||
subdevice { return SUBDEVICE; }
|
||||
action { return ACTION; }
|
||||
match { return MATCH; }
|
||||
nomatch { return NOMATCH; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user