Friday 12 June 2009

Part 1: Monitoring AFP Status in Mac OS X Terminal

There's two freeware apps that might be useful to take a look at before we start:

  1. The first is GeekTool which I've only come across recently. It's a great way to run multiple terminal commands which overlay on top of your desktop, which when you're playing around in unix is a useful way to monitor the output of various commands without continuously having to retype them.
  2. The second is CLIX a useful 'teaching aid' for unix on Mac OS X. I learnt some useful tail and cut commands from CLIX to get just the output from the terminal that I was looking for.

Ok, here we go... At it's essence, Who Is Connected? was designed to monitor AFP and SSH connections in Mac OS X. If all it did initially was to show whether or not AFP and SSH are enabled or not in the menu bar, I'd be happy : )

So this is where I started. How could I achieve this via terminal? Let's take look at Apple File Sharing (AFP) first:

AFP is short for AppleTalk Filing Protocol, a network sharing protocol used in an AppleTalk network. So my starting point was the Apple GUI Network Utility for a unix command Netstat. Network Utility resides in your Applications > Utilities folder and you can click on Netstat in the tabs across the top. Here you can find some pretty verbose information regarding your current network status.

Choosing the option: Display the state of all current socket connections gives a long list of all local and foreign addresses, connections and port numbers. You can return the same output by opening Terminal (Applications > Utilities) and typing:

netstat -a

The -a option shows the status of all sockets including those used by server processes i.e. afp.

If you look down this list, and you have Apple File Sharing enabled in System Preferences, you'll notice that the output includes the lines:

Proto Recv-Q Send-Q Local Address Foreign Address

tcp4 0 0 *.afpovertcp *.* LISTEN

tcp6 0 0 *.afpovert *.* LISTEN


Netstat is telling us that there is a server process LISTEN-ing for remote connections from any address (*.*) that want to connect to a service running on the local machine called afpovertcp (afp-over-tcp).


Disable Apple File Sharing in System Preferences and run Netstat again. This line disappears i.e. the computer is no longer listening for incoming AFP connections.


Great! so netstat tells us whether or not AFP is enabled in System Preferences. But I don't want to navigate through the verbose output of nestat each time to view this. Fortunately, there are various unix commands to help us limit the output of netstat to just what we are looking for.


First, we can limit the output of nestat and speed up it's response by limiting the results it returns to look at one particular address family, in this case we can use inet6:


netstat -a -f inet6


Try it! Secondly we can 'pipe' the output of netstat through grep - to limit the output to the exact line that we are looking for:


netstat -a -f inet6 | grep afpovert


This command firstly runs netstat -a -f inet6 but only returns the lines which include the text afpovert. i.e. grep is acting like a filter to return only the lines we are interested in. Here's the result:


tcp6 0 0 *.afpovert *.* LISTEN


However, the response time is still slower that what I'd like as netstat is still having to run a command to investigate all network connections on the inet6 family of addresses, before it returns its result subsequently filtered by grep. If you're running Tiger, you'll see what I mean.


If we look at the options of netstat:


man nestat


We find we can add the -n option to only show us port numbers rather than an interpreted symbolic address i.e. if we know what port number AFP is running on, we can look for this in netstat's output, rather than asking netstat to do extra work of displaying the symbolic address of all connections. Fortunately, AFP consistently runs on port 548 so we can change our command to:


netstat -naf inet6 | grep 548


Great! an instant result:


tcp6 0 0 *.548 *.* LISTEN


So if I run this command and it returns a result, then I know that AFP is enabled in my System Preferences. Or do I?


Actually, my grep command isn't sophisticated enough. What if there is a different service running on port 5482? or 1548? or any combination of numbers which includes the pattern 548? We will then return an incorrect result as to whether file sharing is enabled or not. We need to improve our grep filter to match exactly what we are looking for in netstat's result.


Lets first ensure we include the *. before the 548 so no numbers can preceed the actual port value we are looking for:


netstat -naf inet6 | grep [*][.]548


As * and . are special characters as part of regular expressions, we need to surround them each with a [ square brace ]. Finally we want to ensure there is a blank space character after 548. To do this, we need to use an escape character \ and a space surrounded by square braces to ensure we force grep to pattern match exactly the number we are looking for. Our expression then becomes:


netstat -naf inet6 | grep [*][.]548[\ ]


For good measure, lets also ask grep to also only return results from netstat of connections which are actively listening for connections, as the AFP service should do:


netstat -naf inet6 | grep [*][.]548[\ ].*LIST


The . after the square brace means 'concatenate' or add the next thing that comes to the query. The following * effectively means: any number of characters inbetween the end of the space character we've just looked for until the next pattern. LIST is for LISTEN in order to remove pattern matching of other connections from the list e.g. ESTABLISHED etc...


So here we have our command for checking if AFP is enabled:


netstat -naf inet6 | grep [*][.]548[\ ].*LIST


phew!


No comments:

Post a Comment