Analysis to collect IP, MAC Address, and DHCP Status for Mac Computers

This is awesome! Thanks. When I put it into the analysis, the return is “multiple results.” Can we get just the Ethernet, Ethernet’s results?

You can, though the user defined friendly name may not always be “Ethernet” I believe.

If you hover over “multiple results” with your mouse, it will pop up the actual results. You will also see the full results if you go to the computer summary.


strings "ConfigMethod" of dictionaries "IPv4" of dictionaries whose("Ethernet" is contained by string "UserDefinedName" of dictionaries "Interface" of it) of values of entries of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

This works for reporting back all of the possible configurations, but I have run into a problem when there are multiple “Locations” setup in Network Preferences.

If you look at the previously mentioned PLIST, you will see that there is a way to get just the active information, but I do not have a solid enough understanding of relevance to get it, hoping someone can help. Here are the components, all of them are inside the preferences.plist file.

dictionary “current set” contains the current Locations (with a preceding “/Sets/”).
dictionary “Sets” has the string (minus ‘/Sets’) that is currently active.
inside of of the active set there is a dictionary Service that list more dictionaries with the configuration keys.
the keys are linked to the NetworkServices dictionary.

So using the object “name of primary internet connection” to get the active connection, is there any way to get the current set, look up the services assigned to it, look into the dictionaries matching the service keys, filter the (name of primary internet connection) and get the ConfigMethod strings.

Thanks.

Chris

1 Like

Yes, it can be done, but it isn’t easy.

This is all of the DeviceNames of the entries:

strings "DeviceName" of dictionaries "Interface" of dictionaries of values of entries of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

Here is how you get the “en0” dictionary specifically so that any subkeys can be queried:

dictionaries whose("en0" = string "DeviceName" of dictionary "Interface" of it) of values of entries of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

Here is how you get that same dictionary, but by first getting the name of the primary internet connection dynamically instead of always getting en0:

dictionaries whose((name of primary internet connection) = string "DeviceName" of dictionary "Interface" of it) of values of entries of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

It is possible to query the Sets dictionary the same way, by using either the current set or by using name of primary internet connection or both.

This will give the value of the CurrentSet:

(following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

This will give you the dictionaries of all sets so the sub elements can be queried:

dictionaries of values of entries of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

This will give you only the Set dictionary of the CurrentSet:

dictionaries of values of entries whose((unique value of (following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")= key of it) of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

It is important to note that the following is not so much an error message, as it is warning you that the selected object does not have a direct string representation:

E: The operator "string" is not defined.

It is confusing, but that is what you should see when you select a dictionary directly.

Nice, so that is well over half way there. I came up with something close for the listing of the active “Location”, and thanks for the tip on the “string is not defined” error.

keys of dictionary "Service" of dictionary "Network" of dictionary (following text of last "/" of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist") of dictionary "Sets" of dictionary of file "/Library/Preferences/SystemConfiguration/preferences.plist"

But now that we have the two pieces (1. all dictionaries from the primary internet connection, 2. all dictionaries from the “CurrentSet”), how would you find the unique dictionary/entry that would be the active internet connection for the “CurrentSet”, and how do you use it if it doesn’t have a direct string representation?

Thanks.
Chris

It might help if you tell me what you are looking to get as the result.

Doesn’t the current set match the current primary internet connection? It does on my machine. I’m not certain if it always does or what it means.

Yea, so it worked great for me on my desktop also, then I tested it on my laptop and I found the issue.

So if you create a second (or third or fourth) “Location” under the System Preference’s Network pane, you will get more configurations and sets of configurations showing up in the file. That is why I need to find what the current “Set” is (thank you), then only pull the primary internet connection from that set. I’m thinking it may need to be an intersection or something, but I am relatively new to this an still figuring it out.

What I am trying to do is pretty simple. I just want to know if the system is using DHCP or assigning itself a static IP. The only caveat is that I do NOT want to have to run a script to write to a file. Instead I want to only use relevance.

Chris

1 Like

Ah, okay. So you need en0 from the current set, assuming en0 is the current connection. I can do that.

It is a bit hard to wrap my head around it when I don’t have a large enough sample size to pull from to understand the need, but I definitely understand it now.

Awesome!

It took me a while to wrap my head around it as well. I was looking at trying to solve it three different ways, and ended up on this path, as it seems to be the one that is most dynamic and should require the least number of moving parts.

2 Likes

This should be what you are looking for:

entries whose((name of primary internet connection) = key of it) of dictionaries "Interface" of dictionaries "Network" of dictionaries of values of entries whose((unique value of (following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")= key of it) of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

Wish it was! Unfortunately it looks like it is looking in the wrong dictionary. I’m closer and will post an update ASAP.

Do you mean that you don’t want the Interface Dictionary?

It would be helpful if you posted an example preferences.plist that has the issue of multiple items and tell me which part you want to get. You can redact any specific info, just keep the keys.

I labeled it as well, as it gets a bit crazy. Here is what I was thinking. It seems like everything is already here, i just don’t know how to glue it all together. Any help is VERY appreciated!

  1. Get the “CurrentSet”
    2 & 3) Get the service ID’s for that set.
    4 & 5) Look at those specific services and search for…
  2. Dictionary which has the “current internet connection” listed under “DeviceName” and
  3. Return the string of “ConfigMethod” for the dictionary, which should be the current connection’s information.

Makes total sense, right? HAHAHAHAHAHAHA It’s crazy complicated I know.

1 Like

Ah, okay.

It is hard to see how these all fit together when my machine does not have a bunch of those.

Here are the service IDs for the current set: (#3)

keys of dictionaries "Service" of dictionaries "Network" of dictionaries of values of entries whose((unique value of (following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")= key of it) of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

Here is #4&5: (this is the keys only, but entries are needed to do the filtering and further examination)

keys of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

This should be the set of NetworkServices keys that are in the current set:

keys of entries whose( key of it is contained by set of ( keys of dictionaries "Service" of dictionaries "Network" of dictionaries of values of entries whose((unique value of (following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")= key of it) of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist" ) ) of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"
1 Like

Final Answer:

strings "ConfigMethod" of dictionaries "IPv4" of dictionaries of values of entries whose( ( (name of primary internet connection) = unique value of strings "DeviceName" of dictionaries "Interface" of dictionaries of values of it) AND key of it is contained by set of ( keys of dictionaries "Service" of dictionaries "Network" of dictionaries of values of entries whose((unique value of (following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")= key of it) of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist" ) ) of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"
1 Like

holy cow.

I want to flood this message with emoticons of joy! :+1: :joy:

Thank you so much. I’m going to go dissect this now so I can better understand it.

2 Likes

Up above are many of the pieces of the relevance used to build up to the final answer, but to really understand it all, you really need to start with the “end” and work backwards.

This is what you want, but for all, unfiltered:

strings "ConfigMethod" of dictionaries "IPv4" of dictionaries of values of entries of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist"

the result on my system:

A: DHCP
A: PPP
A: DHCP
A: DHCP
A: DHCP
A: DHCP

The final answer is the same, just filtering out everything except for the current connection in the current set.

The screenshot you provided was very helpful to help me figure out what needed to be filtered out, why, and how to go about it.

1 Like

Being as OS X lacks an inspector for “dhcp enabled of network adapter”, I’m trying to adapt this to confirm whether an adapter in the current set is both Ethernet and DHCP.

This returns the adapters…

((( keys of dictionaries "Service" of dictionaries "Network" of dictionaries of values of entries whose ( (unique value of (following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")= key of it) of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist" ) ) of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")

…but how should I constrain it? I get the idea it should be something like "key whose ( (dictionary “Inferface” of it contains string “Ethernet” of key “Type”) and (dictionary “IPv4” of it contains string “DHCP” of key “ConfigMethod”) ) … but I can’t quite suss it out.

I adapted this to return on machines using DHCP on a particular subnet:

exists match (regex "Automatic|DHCP") of (strings "ConfigMethod" of dictionaries "IPv4" of dictionaries of values of entries whose( ( (name of (adapters of network) whose (cidr string of it = "127.0.0.0/24")) = unique value of strings "DeviceName" of dictionaries "Interface" of dictionaries of values of it) AND key of it is contained by set of ( keys of dictionaries "Service" of dictionaries "Network" of dictionaries of values of entries whose((unique value of (following texts of firsts "/Sets/" of it) of strings "CurrentSet" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")= key of it) of dictionaries "Sets" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist" ) ) of dictionaries "NetworkServices" of dictionaries of files "/Library/Preferences/SystemConfiguration/preferences.plist")

(“127.0.0.0/24” is a placeholder, of course. Change as needed.)