DEV Community

Higor Diego
Higor Diego

Posted on

Find out how to use Google to locate your home using just your Wi-Fi router!

Wifi Google

Did you know that Google has a location search engine called "Wifi access point object"? This functionality is described in detail in the documentation, which you can check out by clicking here.

It's really amazing, isn't it? Let's explore this feature further!

Have you heard of BSSID? Also known as Basic Service Set Identifier, this term may sound complicated, but it's actually quite useful for understanding how your Wi-Fi router works. The BSSID is like a unique "name" given to the router, allowing your devices to identify it on the network.

Think of the BSSID as a MAC address for your router. It plays a crucial role in enabling your devices to connect to it quickly and efficiently. When scanning for available Wi-Fi networks on your device, you can see the BSSID as a combination of letters and numbers.

Why is this important? Well, understanding the BSSID can be extremely helpful when setting up or troubleshooting issues on your wireless network. It helps identify the specific router you're connecting to, which can be useful when adjusting settings or resolving connection problems.

So, the next time you come across the term BSSID, remember that it refers to the unique identifier of your Wi-Fi router. It's a key element in ensuring a stable and reliable connection in your home or workplace network.

If you want to view the BSSIDs of Wi-Fi routers around you, we have a simple command for you. Here's how:

Open the terminal and type the following command:



sudo /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -s



Enter fullscreen mode Exit fullscreen mode

It's important to run the above command with administrator privileges to ensure you have access to the necessary information. For security reasons, the BSSID will not be displayed if you run the command without proper permissions.

The terminal output will look similar to this:



            SSID BSSID             RSSI CHANNEL HT CC SECURITY (auth/unicast/group)
    "confidencial" XX:5f:67:XX:c5:4d -81  8       Y  -- RSN(PSK/AES/AES) 
    "confidencial" 00:31:92:XX:e7:36 -50  9       Y  -- RSN(PSK/AES/AES) 
    "confidencial" cc:06:XX:db:e2:XX -50  4       Y  -- RSN(PSK/AES/AES) 
        "confidencial" a4:XX:a4:ed:XX:7c -47  2       Y  BR WPA(PSK/AES,TKIP/TKIP) RSN(PSK/AES,TKIP/TKIP) 
"confidencial" cc:06:77:db:e2:84 -66  36,+1   Y  -- RSN(PSK/AES/AES) 
    "confidencial" 00:31:XX:XX:e7:37 -57  48,-1   Y  BR RSN(PSK/AES/AES) 
  "confidencial", fa:XX:ca:86:ca:96 -26  6       Y  -- NONE
      "confidencial" a4:6d:a4:XX:33:XX -49  36      Y  BR WPA(PSK/AES,TKIP/TKIP) RSN(PSK/AES,TKIP/TKIP) 



Enter fullscreen mode Exit fullscreen mode

Once you have obtained the BSSID of the desired Wi-Fi router, you can use the Google API to obtain accurate geolocation data. Here's how to do it using a simple command in the terminal:



curl --location --request GET 'https://www.googleapis.com/geolocation/v1/geolocate?key=YourAPIKeyHere' \
--header 'Content-Type: application/json' \
--data '{
    "wifiAccessPoints":[ 
        {
            "macAddress": "BSSIDOfTheRouterHere" 
        }
    ]
}'


Enter fullscreen mode Exit fullscreen mode

Before proceeding, it's important to replace "YourAPIKeyHere" with your Google API key, which you can obtain by creating a developer account on the Google Cloud Platform. Be sure to add the correct key to ensure proper access to the API.

When you run the command, the system will send a GET request to the Google Geolocation API, passing the router's BSSID as a parameter. This allows Google to identify the approximate location of the router based on its geolocation information.

Furthermore, by examining the structure of the example calls, you can input multiple Wi-Fi MAC addresses along with signal strength. This way, the API will use triangulation techniques to provide an even more accurate location.

It's worth noting that the geolocation API can also find locations based on cell tower IDs. This means you can obtain accurate location information even when you're not connected to a Wi-Fi network.

Now let's create some code to automate the above process using the Go programming language.

Here's the code:



package main

import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"os/exec"
"runtime"
"strings"
)

func getWifiMacAddresses() map[string]map[string]string {
var results []byte
var err error

<span class="k">switch</span> <span class="n">runtime</span><span class="o">.</span><span class="n">GOOS</span> <span class="p">{</span>
<span class="k">case</span> <span class="s">"darwin"</span><span class="o">:</span>
    <span class="n">results</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport"</span><span class="p">,</span> <span class="s">"-s"</span><span class="p">)</span><span class="o">.</span><span class="n">Output</span><span class="p">()</span>
<span class="k">case</span> <span class="s">"windows"</span><span class="o">:</span>
    <span class="n">results</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"netsh"</span><span class="p">,</span> <span class="s">"wlan"</span><span class="p">,</span> <span class="s">"show"</span><span class="p">,</span> <span class="s">"network"</span><span class="p">)</span><span class="o">.</span><span class="n">Output</span><span class="p">()</span>
<span class="k">case</span> <span class="s">"linux"</span><span class="o">:</span>
    <span class="n">results</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"iwlist"</span><span class="p">,</span> <span class="s">"scanning"</span><span class="p">)</span><span class="o">.</span><span class="n">Output</span><span class="p">()</span>
<span class="p">}</span>

<span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
    <span class="n">log</span><span class="o">.</span><span class="n">Fatal</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">var</span> <span class="n">macAddr</span> <span class="o">=</span> <span class="nb">make</span><span class="p">(</span><span class="k">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="k">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">)</span>
<span class="n">lines</span> <span class="o">:=</span> <span class="n">strings</span><span class="o">.</span><span class="n">Split</span><span class="p">(</span><span class="n">strings</span><span class="o">.</span><span class="n">TrimSpace</span><span class="p">(</span><span class="kt">string</span><span class="p">(</span><span class="n">results</span><span class="p">)),</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">)[</span><span class="m">1</span><span class="o">:</span><span class="p">]</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">line</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">lines</span> <span class="p">{</span>
    <span class="n">fields</span> <span class="o">:=</span> <span class="n">strings</span><span class="o">.</span><span class="n">Fields</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
    <span class="n">addr</span> <span class="o">:=</span> <span class="n">fields</span><span class="p">[</span><span class="m">0</span><span class="p">]</span>
    <span class="n">db</span> <span class="o">:=</span> <span class="n">fields</span><span class="p">[</span><span class="m">1</span><span class="p">]</span>
    <span class="c">// additional fields if needed</span>

    <span class="n">macAddr</span><span class="p">[</span><span class="n">addr</span><span class="p">]</span> <span class="o">=</span> <span class="k">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
        <span class="s">"signalStrength"</span><span class="o">:</span> <span class="n">db</span><span class="p">,</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">return</span> <span class="n">macAddr</span>
Enter fullscreen mode Exit fullscreen mode

}

func main() {
postjson := make(map[string]interface{})
postjson["wifiAccessPoints"] = []map[string]interface{}{}
hotspots := getWifiMacAddresses()

<span class="k">for</span> <span class="n">addr</span><span class="p">,</span> <span class="n">info</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">hotspots</span> <span class="p">{</span>
    <span class="n">signalStrength</span> <span class="o">:=</span> <span class="n">info</span><span class="p">[</span><span class="s">"signalStrength"</span><span class="p">]</span>
    <span class="n">postjson</span><span class="p">[</span><span class="s">"wifiAccessPoints"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">append</span><span class="p">(</span><span class="n">postjson</span><span class="p">[</span><span class="s">"wifiAccessPoints"</span><span class="p">]</span><span class="o">.</span><span class="p">([]</span><span class="k">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="k">interface</span><span class="p">{}),</span> <span class="k">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="k">interface</span><span class="p">{}{</span>
        <span class="s">"macAddress"</span><span class="o">:</span>     <span class="n">addr</span><span class="p">,</span>
        <span class="s">"signalStrength"</span><span class="o">:</span> <span class="n">signalStrength</span><span class="p">,</span>
    <span class="p">})</span>
<span class="p">}</span>

<span class="n">googleMapsAPIkey</span> <span class="o">:=</span> <span class="s">"your_google_maps_api_key"</span>
<span class="n">url</span> <span class="o">:=</span> <span class="s">"https://www.googleapis.com/geolocation/v1/geolocate?key="</span> <span class="o">+</span> <span class="n">googleMapsAPIkey</span>

<span class="n">data</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Marshal</span><span class="p">(</span><span class="n">postjson</span><span class="p">)</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
    <span class="n">log</span><span class="o">.</span><span class="n">Fatal</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="p">}</span>

<span class="n">response</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">http</span><span class="o">.</span><span class="n">Post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="s">"application/json"</span><span class="p">,</span> <span class="n">bytes</span><span class="o">.</span><span class="n">NewBuffer</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
    <span class="n">log</span><span class="o">.</span><span class="n">Fatal</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">defer</span> <span class="n">response</span><span class="o">.</span><span class="n">Body</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>

<span class="k">var</span> <span class="n">result</span> <span class="k">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="k">interface</span><span class="p">{}</span>
<span class="n">json</span><span class="o">.</span><span class="n">NewDecoder</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">Body</span><span class="p">)</span><span class="o">.</span><span class="n">Decode</span><span class="p">(</span><span class="o">&amp;</span><span class="n">result</span><span class="p">)</span>

<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
Enter fullscreen mode Exit fullscreen mode

}

Enter fullscreen mode Exit fullscreen mode




Conclusion

In this blog post, we explored how to use the Go programming language to automate the retrieval of Wi-Fi MAC addresses and leverage the Google Geolocation API. With the developed code, it's possible to obtain accurate information about nearby Wi-Fi routers and send them to the API, thereby obtaining an approximate location.

I hope this was helpful. Until next time! (:

Top comments (0)