anchor.diff:      call(is_network_up).
   
   subscribe() ->
  -    call(subscribe).
  +    subscribe(all, operstate).
  +
  +subscribe(Iface) ->
  +    subscribe(Iface, operstate).
  +
  +subscribe(Iface, Field) ->
  +    call({subscribe, Iface, Field}).
   
   start_link() ->
       gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
   
   init(_) ->
  -    {ok, #st{}}.
  +    Ref = case code:is_loaded(netlink_drv) of
  +              false ->
  +                  %% Must fake event mechanism through polling
  +                  start_poll_timer();
  +              {file, _} ->
  +                  netlink:subscribe("", [operstate], [flush]),
  +                  undefined
  +          end,
  +    Interfaces = get_interfaces(),
  +    {ok, #st{ifs = Interfaces,
  +             poll_ref = Ref}}.
   
   handle_call(is_network_up, _From, #st{connected = Conn} = St) ->
       {reply, Conn, St};
  -handle_call(subscribe, {Pid, _}, #st{subscribers = Subs} = St) ->
  +handle_call({subscribe, Iface, Field}, {Pid, _},
  +            #st{subscribers = Subs} = St) ->
       Ref = erlang:monitor(process, Pid),
  -    {reply, ok, St#st{subscribers = [{Pid, Ref}|Subs]}};
  +    {reply, ok, St#st{subscribers = [#sub{name = Iface,
  +                                          field = Field,
  +                                          pid = Pid,
  +                                          ref = Ref}|Subs]}};
   handle_call(_, _From, St) ->
       {reply, ?BADARG, St}.
   
   handle_cast(_, St) ->
       {noreply, St}.
   
  +handle_info({timeout, _Ref, poll}, #st{ifs = Ifs} = S) ->
  +    NewPollRef = start_poll_timer(),
  +    NewIfs = get_interfaces(),
  +    Diffs = lists:foldr(
  +              fun(#iface{name = Name, status = St}, Acc) ->
  +                      case lists:keyfind(Name, #iface.name, Ifs) of
  +                          #iface{status = St0} when St0 =/= St ->
  +                              [{Name, operstate, St0, St}|Acc];
  +                          _ ->
  +                              Acc
  +                      end
  +              end, [], NewIfs),
  +    {noreply, tell_subscribers(Diffs, S#st{ifs = NewIfs,
  +                                           poll_ref = NewPollRef})};
  +handle_info({netlink, NRef, Iface, Field, Prev, New}, St) ->
  +    {Prev1, New1} = adjust_status(IFace, Field, Prev, New),
  +    {noreply, tell_subscribers([{Iface, Field, Prev1, New1}], St)};
   handle_info(_, St) ->
       {noreply, St}.
   
  
positive.code: -behaviour(gen_server).
  
  -export([is_network_up/0,
           subscribe/0]).
  
  -export([start_link/0]).
  
  
negative.code:          terminate/2,
           code_change/3]).
  
  -record(iface, {name,
                  status = down,
                  opts = []}).
  
  -record(sub, {name, field, pid, ref}).
  
  -record(st, {connected = false,
               ifs = [],
               subscribers = [],
               poll_ref}).
  
  -define(BADARG, {?MODULE, '__BADARG__'}).
  
  