Finding services advertised with Bonjour via Flame

Have you ever had an issue with someone sharing an iTunes library, and you want to quickly track down the IP of the offending user?

Here is a quick little guide on getting that done.

dns-sd is a service discovery application that can make tracking down users sharing various information quite easily. It also has a great API for accessing various information about local DNS information, and setting local DNS advertising quite easily.

First, an example:

dns-sd -B _daap._tcp
This command checks for bonjour iTunes shared libraries (daap protocol, tcp, .local subnet).
Output:
Browsing for _daap._tcp
Timestamp   A/R Flags if Domain Service Type Instance Name
9:31:12.844  Add  3  4 local.  _daap._tcp.   local’s Library_PW
9:31:12.844  Add  2  1 local.  _daap._tcp.   local’s Library_PW
local:~ local$ dns-sd -L "local’s Library_PW" _daap._tcp
Lookup local’s Library_PW._daap._tcp.local
local’s Library._daap._tcp.local. can be reached at
local.local.:3689
(interface 1)
Flags: 1
txtvers=1 iTSh
Version=196609
MID=************
Database ID=D18C43A55BFAC99B
dmv=131078
Version=196616
OSsi=0x1F8
Machine Name=local’s Library Media
Kinds Shared=3145839
Machine ID=************
Password=1

With these commands, it gives you the hostname, which you can always resolve by pinging it. This is a slightly edited output for readability. (spaces and newlines are escaped in the shell, but you see all the slashes)

How is this better than other solutions like Flame or Bonjour Browser?
Well, with this approach, we can actually script the entire event into one bash script, without too much work.
A minute of checking the man pages for sed and cut yields:

#!/bin/bash
# create semi-random filenames for writing and reading to
tempfoo=`basename $0`
TFILE=`mktemp /tmp/XXXXXX` || exit 1
TFILE2=`mktemp /tmp/2XXXXXX` || exit 1
# grabs browseable list of bonjour shared libraries
dns-sd -B _daap._tcp 1>$TFILE &
# grab the process identifiers for the dns-sd process WHICH NEVER STOPS
TFILE_PID=$!
sleep 1
# takes the last library in the list and formats it for dns-sd -L
res=$(tail -n1 $TFILE | awk '{gsub(/[ ]+/," ")}1' | cut -d' ' -s -f6-)
# read the protocol and then name in, allows us to use different protocols in the future
read -r protocol name << "$res"
# look up specific libraries
dns-sd -L "$name" "$protocol" 1>$TFILE2 &
# grab the process identifiers for the dns-sd process WHICH NEVER STOPS
TFILE2_PID=$!
# we have to wait a second because dns-sd -L can take a while to respond
sleep 1
res2=$(cat $TFILE2 | awk '{gsub(/[ ]+/," ")}1')
# for some reason cut wasnt respecting the spaces, but in another var it worked fine
ip=$(echo $res2 | cut -d' ' -f10| cut -d'.' -f1-2)
if [[ "$ip" == "" ]]
then echo "No computers are sharing their libraries"
else ping $whoa1
fi
# kill the dns-sd processes
# remove the temporary files
kill $TFILE_PID
kill $TFILE2_PID
rm $TFILE
rm $TFILE2

…and by a minute, I meant more like an hour. I commented most of the material, and the source can also be found at https://gist.github.com/ConstantineK/d2179abf2f31c041c1e1.

A lot more went into this than initially expected, but that is always the case when it comes to bash.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.