diff options
author | Jordan Bracco <href@random.sh> | 2021-11-06 22:11:00 +0100 |
---|---|---|
committer | Jordan Bracco <href@random.sh> | 2021-11-06 22:11:00 +0100 |
commit | 756e5aaf9deb0900962f91ebac30e8a756884717 (patch) | |
tree | 42036da0c0cba79ff9353826e7d53013bd3a2a81 /test |
Diffstat (limited to 'test')
-rw-r--r-- | test/pf_route_freebsd_SUITE.erl | 110 | ||||
-rw-r--r-- | test/pf_route_macos_SUITE.erl | 195 |
2 files changed, 305 insertions, 0 deletions
diff --git a/test/pf_route_freebsd_SUITE.erl b/test/pf_route_freebsd_SUITE.erl new file mode 100644 index 0000000..7bb7e1f --- /dev/null +++ b/test/pf_route_freebsd_SUITE.erl @@ -0,0 +1,110 @@ +-module(pf_route_freebsd_SUITE). +-compile(export_all). +-compile(nowarn_export_all). +-include_lib("pf_route/src/pf_route.hrl"). +-include_lib("pf_route/src/pf_route_freebsd.hrl"). +-include_lib("stdlib/include/assert.hrl"). + +suite() -> + [{timetrap, 10000}]. + +all() -> + [{group, pf_route_parser}, {group, netstat_parser}]. + +groups() -> + [{pf_route_parser, [parallel], pf_route_parser_tests()}, {netstat_parser, [parallel], netstat_parser_tests()}]. + +init_per_group(_Group, Config) -> + Config. + +end_per_group(_, _) -> + ok. + +%% Netstat + +netstat_parser_tests() -> + [netstat_list]. + +netstat_list(_) -> + {skip, todo}. + +%% Packet + +pf_route_parser_tests() -> + [pckt_rt_add, pckt_rt_delete, pckt_rt_get, pckt_rt_get_default]. + +pckt_rt_add(_) -> + ct:comment("Simple RT_ADD"), + Binary = <<5,1,3,0,0,0,67,8,0,0,7,0,0,0,14,32,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0,192,168,168,0,0,0,0,0,0,0,0,0,16, + 2,0,0,192,168,1,1,0,0,0,0,0,0,0,0,16,2,0,0,255,255,255,0,0,0,0,0,0,0,0, + 0>>, + Rt = pf_route_freebsd:parse_pf_route_packet(Binary), + ?assertEqual(add, Rt#freebsd_rt.type), + ?assertEqual([up, gateway, done, static], Rt#freebsd_rt.flags), + ?assertEqual([destination, gateway, netmask], Rt#freebsd_rt.addrs), + ?assertEqual(73742, Rt#freebsd_rt.pid), + ?assertEqual(1, Rt#freebsd_rt.seq), + ?assertEqual({192, 168, 168, 0}, Rt#freebsd_rt.destination), + ?assertEqual({255, 255, 255, 0}, Rt#freebsd_rt.netmask), + ?assertEqual({192, 168, 1, 1}, Rt#freebsd_rt.gateway), + ?assertEqual(3, Rt#freebsd_rt.ifp_index). + +pckt_rt_delete(_) -> + ct:comment("Simple RT_DELETE"), + Binary = <<5,2,3,0,0,0,66,8,0,0,7,0,0,0,82,33,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0,192,168,168,0,0,0,0,0,0,0,0,0, + 16,2,0,0,192,168,1,1,0,0,0,0,0,0,0,0,16,2,0,0,255,255,255,0,0,0,0,0,0, + 0,0,0>>, + Rt = pf_route_freebsd:parse_pf_route_packet(Binary), + ?assertEqual(delete, Rt#freebsd_rt.type), + ?assertEqual([gateway, done, static], Rt#freebsd_rt.flags), + ?assertEqual([destination, gateway, netmask], Rt#freebsd_rt.addrs), + ?assertEqual(74066, Rt#freebsd_rt.pid), + ?assertEqual(1, Rt#freebsd_rt.seq), + ?assertEqual({192, 168, 168, 0}, Rt#freebsd_rt.destination), + ?assertEqual({255, 255, 255, 0}, Rt#freebsd_rt.netmask), + ?assertEqual({192, 168, 1, 1}, Rt#freebsd_rt.gateway), + ?assertEqual(3, Rt#freebsd_rt.ifp_index). + +pckt_rt_get(_) -> + ct:comment("RT_GET"), + Binary = <<5,4,3,0,0,0,65,0,16,0,55,0,0,0,62,56,1,0,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0,192,168,1,0,0,0,0,0,0,0,0,0, + 16,18,3,0,6,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0,255,255,255,0,0,0,0,0,0,0,0, + 0,56,18,3,0,6,5,6,0,108,111,99,97,108,10,96,213,0,0,0,10,96,213,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0, + 192,168,1,7,0,0,0,0,0,0,0,0>>, + Rt = pf_route_freebsd:parse_pf_route_packet(Binary), + ?assertEqual(get, Rt#freebsd_rt.type), + {skip, todo}. + +pckt_rt_get_default(_) -> + ct:comment("RT_GET default"), + Binary = <<5,4,5,0,0,0,67,8,0,0,55,0,0,0,254,59,1,0,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,16,2,0,0,45,150,148,1,0,0,0,0,0,0,0,0,16,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,56,18,5,0,6,7,6,0,97,115,52,51,48,54,57,2,96,213,16,21,42, + 213,16,21,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,16,2,0,0,45,150,148,7,0,0,0,0,0,0,0,0>>, + Rt = pf_route_freebsd:parse_pf_route_packet(Binary), + ?assertEqual(get, Rt#freebsd_rt.type), + ?assertEqual([up, gateway, done, static], Rt#freebsd_rt.flags), + ?assertEqual([destination, gateway, netmask, ifp, ifa], Rt#freebsd_rt.addrs), + ?assertEqual(1400, Rt#freebsd_rt.mtu), + ?assertEqual({0, 0, 0, 0}, Rt#freebsd_rt.destination), + ?assertEqual({0, 0, 0, 0}, Rt#freebsd_rt.netmask), + ?assertEqual({45, 150, 148, 1}, Rt#freebsd_rt.gateway), + ?assertEqual(5, Rt#freebsd_rt.ifp_index). diff --git a/test/pf_route_macos_SUITE.erl b/test/pf_route_macos_SUITE.erl new file mode 100644 index 0000000..c48abc9 --- /dev/null +++ b/test/pf_route_macos_SUITE.erl @@ -0,0 +1,195 @@ +-module(pf_route_macos_SUITE). +-compile(export_all). +-compile(nowarn_export_all). +-include_lib("pf_route/src/pf_route.hrl"). +-include_lib("pf_route/src/pf_route_macos.hrl"). +-include_lib("stdlib/include/assert.hrl"). + +suite() -> + [{timetrap, 10000}]. + +all() -> + [{group, pf_route_parser}, {group, netstat_parser}]. + +groups() -> + [{pf_route_parser, [parallel], pf_route_parser_tests()}, {netstat_parser, [parallel], netstat_parser_tests()}]. + +init_per_group(_Group, Config) -> + Config. + +end_per_group(_, _) -> + ok. + + +%% Netstat + +netstat_parser_tests() -> + [netstat_list]. + +netstat_list(_) -> + {skip, todo}. + + +%% Packet + +pf_route_parser_tests() -> + [pckt_rt_add, pckt_rt_add_error, pckt_rt_add_expire, pckt_rt_delete, pckt_rt_delete_2, pckt_rt_get, pckt_rt_get_default, pckt_rt_ifinfo, pckt_rt_deladdr]. + +%% Result of `route add 192.168.3.0/24 8.8.8.8`. +pckt_rt_add(_) -> + ct:comment("RT_ADD"), + Binary = <<5,1,0,0,0,0,67,8,0,0,7,0,0,0,21,130,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0, + 192,168,3,0,0,0,0,0,0,0,0,0,16,2,0,0,8,8,8,8,0,0,0,0,0,0,0,0,7,2 + ,0,0,255,255,255,0>>, + {ok, Rt} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_rt{} = Rt, + ?assertEqual(add, Rt#macos_rt.type), + ?assertEqual([up, gateway, done, static], Rt#macos_rt.flags), + ?assertEqual([destination, gateway, netmask], Rt#macos_rt.addrs), + ?assertEqual(33301, Rt#macos_rt.pid), + ?assertEqual(1, Rt#macos_rt.seq), + ?assertEqual(0, Rt#macos_rt.errno), + ?assertEqual(0, Rt#macos_rt.expire), + ?assertEqual({0, 0, 0}, Rt#macos_rt.filler), + ?assertEqual(#pf_route_inet4{address = {192, 168, 3, 0}}, Rt#macos_rt.destination), + ?assertEqual(#pf_route_inet4{address = {8, 8, 8, 8}}, Rt#macos_rt.gateway), + ?assertEqual(#pf_route_inet4{address = {255, 255, 255, 0}}, Rt#macos_rt.netmask), + ?assertEqual(undefined, Rt#macos_rt.ifp), + ?assertEqual(0, Rt#macos_rt.ifp_index), + ?assertEqual(undefined, Rt#macos_rt.ifa), + ?assertEqual(undefined, Rt#macos_rt.author), + ?assertEqual(undefined, Rt#macos_rt.brd). + +pckt_rt_add_error(_) -> + ct:comment("RT_ADD with error (already existing)"), + Binary = <<5,1,0,0,0,0,3,8,0,0,7,0,0,0,99,228,0,0,1,0,0,0,17,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0, + 0,192,168,3,0,0,0,0,0,0,0,0,0,16,2,0,0,8,8,8,8,0,0,0,0,0,0,0,0, + 7,2,0,0,255,255,255,0>>, + {ok, Rt} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_rt{} = Rt, + ?assertEqual(17, Rt#macos_rt.errno). + +pckt_rt_add_expire(_) -> + ct:comment("RT_ADD with expiry"), + Binary = <<5,1,0,0,0,0,67,8,0,0,7,0,0,0,22,231,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,152,122,97,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 16,2,0,0,192,168,4,0,0,0,0,0,0,0,0,0,16,2,0,0,8,8,8,8,0,0,0,0,0, + 0,0,0,7,2,0,0,255,255,255,0>>, + {ok, Rt} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_rt{} = Rt, + ?assertEqual(1635424292, Rt#macos_rt.expire), + ?assertEqual([expire], Rt#macos_rt.metrics_init). + +pckt_rt_delete(_) -> + ct:comment("RT_DELETE"), + Binary = <<5,2,15,0,0,0,4,0,32,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,30,0,0, + 0,0,0,0,254,128,0,15,0,0,0,0,144,241,224,255,254,211,173,11,0,0, + 0,0,20,18,15,0,6,0,6,0,146,241,224,211,173,11,0,0,0,0,0,0>>, + {ok, Rt} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_rt{} = Rt, + ?assertEqual(delete, Rt#macos_rt.type). + +pckt_rt_delete_2(_) -> + ct:comment("RT_DELETE with ifp/ifa"), + %% RTM_DELETE: Delete Route: len 164, pid: 80, seq 166, errno 0, ifscope 12, flags:<HOST,DONE,WASCLONED,BROADCAST,IFSCOPE,CONDEMNED> + %% locks: inits: + %% sockaddrs: <DST,GATEWAY,IFP,IFA> + %% 172.20.10.15 ff.ff.ff.ff.ff.ff en0:a0.78.17.af.bb.68 172.20.10.13 + Binary = <<5,2,12,0,0,0,68,0,66,3,51,0,0,0,80,0,0,0,166,0,0,0,0,0,0,0,8,0, + 0,0,0,0,0,0,0,0,0,0,220,5,0,0,0,0,0,0,70,51,121,97,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,16,2,0,0,172,20,10,15,0,0,0,0,0,0,0,0,20,18,12,0,6,0,6,0, + 255,255,255,255,255,255,0,0,0,0,0,0,20,18,12,0,6,3,6,0,101,110, + 48,160,120,23,175,187,104,0,0,0,16,2,0,0,172,20,10,13,0,0,0,0,0, + 0,0,0>>, + {ok, Rt} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_rt{} = Rt, + ?assertEqual([host, done, wascloned, broadcast, ifscope, condemned], Rt#macos_rt.flags), + ?assertEqual(12, Rt#macos_rt.ifp_index), + ?assertEqual(#pf_route_inet4{address = {172,20,10,15}}, Rt#macos_rt.destination), + ?assertEqual({macos_link, 12, 6, <<>>, [255, 255, 255, 255, 255, 255], <<>>}, Rt#macos_rt.gateway), + ?assertEqual({macos_link, 12, 6, <<"en0">>, [160, 120, 23, 175, 187, 104], <<>>}, Rt#macos_rt.ifp), + ?assertEqual(#pf_route_inet4{address = {172,20,10,13}}, Rt#macos_rt.ifa). + + +pckt_rt_get(_) -> + ct:comment("RT_GET for a subnet"), + %RTM_GET: Report Metrics: len 168, pid: 69344, seq 1, errno 0, flags:<UP,GATEWAY,DONE,STATIC,PRCLONING> + % locks: inits: + % sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA> + % 192.168.3.0 dns.google (255) ffff ffff ff en0:a0.78.17.af.bb.68 172.20.10.13 + Binary = <<5,4,12,0,0,0,67,8,1,0,55,0,0,0,224,14,1,0,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,220,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16, + 2,0,0,192,168,3,0,0,0,0,0,0,0,0,0,16,2,0,0,8,8,8,8,0,0,0,0,0,0, + 0,0,7,255,255,255,255,255,255,0,20,18,12,0,6,3,6,0,101,110,48, + 160,120,23,175,187,104,0,0,0,16,2,0,0,172,20,10,13,0,0,0,0,0,0, + 0,0>>, + {ok, Rt} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_rt{} = Rt, + ?assertEqual(#pf_route_inet4{address = {192, 168, 3, 0}}, Rt#macos_rt.destination), + ?assertEqual(#pf_route_inet4{address = {8, 8, 8, 8}}, Rt#macos_rt.gateway), + ?assertEqual(#pf_route_inet4{address = {255, 255, 255, 0}}, Rt#macos_rt.netmask). + +pckt_rt_get_default(_) -> + ct:comment("RT_GET default"), + %% RTM_GET: Report Metrics: len 164, pid: 56835, seq 1, errno 0, flags:<UP,GATEWAY,DONE,STATIC,PRCLONING,GLOBAL> + %% locks: inits: + %% sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA> + %% default 172.20.10.1 default en0:a0.78.17.af.bb.68 172.20.10.13 + Binary = <<5,4,12,0,0,0,67,8,1,64,55,0,0,0,3,222,0,0,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,220,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,2,0,0,172,20,10,1,12,0,0,0,0,0, + 0,0,0,0,0,0,20,18,12,0,6,3,6,0,101,110,48,160,120,23,175,187, + 104,0,0,0,16,2,0,0,172,20,10,13,0,0,0,0,0,0,0,0>>, + {ok, Rt} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_rt{} = Rt, + ?assertEqual(get, Rt#macos_rt.type), + ?assertEqual([up, gateway, done, static, prcloning, global], Rt#macos_rt.flags), + ?assertEqual([destination, gateway, netmask, ifp, ifa], Rt#macos_rt.addrs), + ?assertEqual(1500, Rt#macos_rt.mtu), + ?assertEqual(#pf_route_inet4{address = {0, 0, 0, 0}}, Rt#macos_rt.destination), + ?assertEqual(#pf_route_inet4{address = {172, 20, 10, 1}}, Rt#macos_rt.gateway), + ?assertEqual(#pf_route_inet4{address = {0, 0, 0, 0}}, Rt#macos_rt.netmask), + ?assertEqual({macos_link, 12, 6, <<"en0">>, [160, 120, 23, 175, 187, 104], <<>>}, Rt#macos_rt.ifp), + ?assertEqual(12, Rt#macos_rt.ifp_index), + ?assertEqual(#pf_route_inet4{address = {172, 20, 10, 13}}, Rt#macos_rt.ifa). + +pckt_rt_ifinfo(_) -> + ct:comment("RT_IFINFO (new interface)"), + %% RTM_IFINFO: iface status change: len 112, if# 22, flags:<BROADCAST,b6,RUNNING,SIMPLEX,MULTICAST> + Binary = <<5,14,0,0,0,0,35,136,0,0,22,0,0,0,6,0,0,6,14,0,0,0,220,5,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,121,97, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0>>, + {ok, If} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_if{} = If, + ?assertEqual([up, broadcast, notrailers, simplex, multicast], If#macos_if.flags), + ?assertEqual([], If#macos_if.addrs), + ?assertEqual(22, If#macos_if.index), + {skip, If}. + +pckt_rt_deladdr(_) -> + ct:comment("RT_DELADDR"), + Binary = <<5,13,52,0,0,0,0,1,0,0,15,0,0,0,0,0,0,0,28,30,0,0,0,0,0,0,255, + 255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,20,18,15,0, + 6,4,6,0,108,108,119,48,146,241,224,211,173,11,0,0,28,30,0,0,0,0, + 0,0,254,128,0,15,0,0,0,0,144,241,224,255,254,211,173,11,0,0,0,0>>, + {ok, Ifa} = pf_route_macos:parse_pf_route_packet(Binary), + #macos_ifa{} = Ifa, + ?assertEqual(deleted, Ifa#macos_ifa.type), + ?assertEqual([promisc], Ifa#macos_ifa.flags), + ?assertEqual([netmask, ifp, ifa], Ifa#macos_ifa.addrs), + ?assertEqual(15, Ifa#macos_ifa.index), + ?assertEqual(0, Ifa#macos_ifa.metric), + ?assertEqual(#pf_route_inet6{address = {65535,65535,65535,65535,0,0,0,0},flow = 0, scope = 0}, Ifa#macos_ifa.netmask), + ?assertEqual(#macos_link{index = 15, type = 6, name = <<"llw0">>, address = [146, 241, 224, 211, 173, 11], selector = <<>>}, Ifa#macos_ifa.ifp), + ?assertEqual(#pf_route_inet6{address = {33022,3840,0,0,61840,65504,54270,2989},flow = 0, scope = 0}, Ifa#macos_ifa.ifa). |