{"id":22912008,"url":"https://github.com/opencoff/ifscand","last_synced_at":"2025-08-22T12:34:46.437Z","repository":{"id":75757088,"uuid":"78242118","full_name":"opencoff/ifscand","owner":"opencoff","description":"automatically configure OpenBSD WiFi interface","archived":false,"fork":false,"pushed_at":"2018-04-14T20:08:04.000Z","size":81,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-10T12:37:08.253Z","etag":null,"topics":["automatic-interface-management","network-setup","openbsd","openbsd-ports","wifi","wifimanager"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opencoff.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-06T22:02:42.000Z","updated_at":"2024-10-31T05:23:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"f9b36e2f-b25a-4ce7-91f3-abd769ed7434","html_url":"https://github.com/opencoff/ifscand","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/opencoff/ifscand","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencoff%2Fifscand","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencoff%2Fifscand/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencoff%2Fifscand/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencoff%2Fifscand/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opencoff","download_url":"https://codeload.github.com/opencoff/ifscand/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opencoff%2Fifscand/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271638634,"owners_count":24794728,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automatic-interface-management","network-setup","openbsd","openbsd-ports","wifi","wifimanager"],"created_at":"2024-12-14T04:19:33.857Z","updated_at":"2025-08-22T12:34:46.413Z","avatar_url":"https://github.com/opencoff.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"======================================================\n``ifscand`` - Automatic WiFi configuration for OpenBSD\n======================================================\n\n``ifscand`` is a daemon to automatically configure WiFi interfaces on\nOpenBSD. A companion program ``ifscanctl`` provides corresponding\ncontrol - including addition, deletion of WiFi Access Points (AP).\n\nOnce setup, it is entirely automatic - you don't need to fiddle\nwith hostname.if(5) or dhclient(8) to join wireless networks.\n\n**This is written specifically to work ONLY on OpenBSD.**\n\nUsage\n=====\n\n``ifscand``::\n\n    # ifscand [-d] [-f] IFACE\n\nWhere *IFACE* is the WiFi interface that ``ifscand`` should monitor\nand auto-configure.\n\n``ifscanctl``::\n\n    # ifscanctl IFACE command\n\nWhere *command* can be one of::\n\n    add nwid AP [bssid BSSID] [wpakey|nwkey KEY] [lladdr MACADDR] \\\n        [inet dhcp|IP4/MASK4] [gw GW4] [inet6 IP6/MASK6] [gw6 GW6]\n\n    del AP\n\n    list\n\n    scan\n\n    set ap-order AP1 [AP2...]\n\n\n\n\nDesign Details\n==============\n``ifscand`` has the following features:\n\n- configure WiFi link layer (WEP/WPA).\n- associate a static IP address for a specific AP\n- enable DHCP IP address configuration (default) when joining an AP.\n- detect rogue AP - by pinning BSSID to a configured value.\n- randomize client MAC address when joining specific AP or all AP.\n- configure relative order of selecting APs when more than one\n  configured APs are visible.\n\n``ifscand`` begins its operation by scanning for visible APs. It\ndoes this \"full scan\" every 60 seconds. Once it finds one or more APs\nthat it is configured to join, it will sort them based on RSSI\n(signal strength) and picks the one with the highest RSSI.\n\nOnce ``ifscand`` joins an AP, it will further monitor the RSSI of\nthe joined AP every 10 seconds. If the weighted average of the last\n4 RSSI measurements falls below 8%, ``ifscand`` will do a full-scan\nand pick a new AP.\n\n``ifscand`` also configures the interface's IP address. It does this\nby two means:\n\n#. If the AP configuration doesn't have a static IP address\n   configured, ``ifscand`` will start dhclient(8).\n\n#. If the AP configuration has a static IP address configured,\n   ``ifscand`` will run ifconfig(8) and route(8) to setup the\n   interface address and default gateway respectively.\n\n``ifscand`` configures the WiFi link-layer properties by calling\nappropriate ioctl(2).\n\nRationale for Design Choices\n----------------------------\n* WiFi is unlike traditional link layers - users are not tethered to\n  a single link-layer attachment point. And thus, whenever the link\n  layer changes, the corresponding network configuration also\n  changes.\n\n  Thus, it is unwise to make ``ifscand`` only focus on link-layer\n  autoconfig.  If it did only that, then the user has to manually\n  decide whether to start dhclient(8) or ifconfig(8). And, most\n  importantly, there is no easy place in the current schme of\n  hostname.if(5) to express the binding between AP and IP address.\n\n* ``ifscand`` manages lifetime of dhclient(8) because of the\n  following scenario:\n\n    - consider a user's setup where there are two AP's configured:\n      AP1 with DHCP assigned IP address and AP2 with a static IP\n      address.\n\n    - when the user is connected to AP1, dhclient(8) will get a\n      dynamic IP address. \n\n    - If the user \"roams\" out of AP1 and is connected to AP2, then\n      dhclient must cease its operation -- since AP2 has a static IP\n      address assigned.\n\n  Thus, I made the decision to allow ``ifscand`` to control the\n  lifetime of dhclient.\n\n\nFAQ\n===\nHow do I build it?\n------------------\nAssuming you are on an OpenBSD machine::\n\n    $ make\n\n\nHow do I start it?\n------------------\nAs 'root', type::\n\n    # ./ifscand/ifscand IFNAME\n\nWhere 'IFNAME' is the wireless interface for which you want automatic\nscanning and joining. Bear in mind, the above command merely starts\nthe daemon; it doesn't know anything about your access\npoints.\n\nUse ``ifscanctl`` to configure the daemon. See examples below.\n\nShow me some examples\n---------------------\nLet us assume your WiFi interface is **iwm0** and you have an AP\nwith SSID \"myap\" and WPA key \"origami987\".  As 'root' do::\n\n # ./ifscanctl/ifscanctl iwm0 add nwid myap wpakey origami987 inet dhcp\n # ./ifscanctl/ifscanctl iwm0 add nwid \"Google Starbucks\" inet dhcp\n # ./ifscanctl/ifscanctl iwm0 add nwid SomeAP wpakey foobar12345\n\nThe last example remembers ``SomeAP`` - but **without** any network\naddress (IP) configuration.\n\nFor more details, consult the man page for ``ifscanctl``.\n\nHow do I install it permanently?\n--------------------------------\n#. As a non-root user, build the software::\n\n    make\n\n#. As 'root', do the following::\n\n    make install\n\n   This will install the binaries and manpages to */usr/local/bin*\n   and */usr/local/man* respectively.\n   It will also append a fragment to */etc/rc.conf.local*. \n\n#. Edit */etc/rc.conf.local* and configure the ``ifscand`` line with\n   the appropriate WiFi interface for your setup. e.g., if *iwm0* is\n   your WiFi interface, ::\n\n        ifscand_flags=iwm0\n\n#. \"Unconfigure\" ``/etc/hostname.IFNAME`` if you have previously\n   configured the interface manually.\n\n#. Start it for the first time::\n\n    # /etc/rc.d/ifscand start\n\nHow can I prevent leak of my MAC address to some APs\n----------------------------------------------------\n``ifscand`` can randomize MAC addresses prior to joining an AP.\nIn the example above, let us tell ``ifscand`` to use a random MAC\naddress with \"myap\"::\n\n    # ./ifscanctl/ifscanctl iwm0 add nwid myap wpakey origami987 \\\n        lladdr random inet dhcp\n\nNow, ``ifscand`` will pick a random MAC address whenever it joins\n\"myap\".\n\nHow can I be sure that I have joined the AP I previously configured?\n--------------------------------------------------------------------\nWhen you first join an AP, manually verify (using whatever means you\ncan think of) that it is the right one. Once certain, you can teach\n``ifscand`` to pin the AP name to its BSSID. e.g., let us connect to\n\"secureAP\" with a pinned BSSID::\n\n    # ifscanctl iwm0 add nwid secureAP bssid 60:00:0a:13:22:5a \\\n        wpakey histeriana7139 inet dhcp\n\nNow, whenever ``ifscand`` sees the AP \"secureAP\", it will verify that\nit's BSSID is *60:00:0a:13:22:5a*. If it isn't - it will write a\nwarning to syslog and eliminate the AP from the current scan\nconsideration.\n\nHow can I troubleshoot if ``ifscand`` isn't working for me?\n-----------------------------------------------------------\nStart ``ifscand`` in debug mode; it should print more diagnostics to\nsyslog::\n\n    # ifscand -d IFNAME\n\nNow, look at */var/log/daemon*; ``ifscand`` prints messages with the\nprefix \"ifscand.IFNAME\" where \"IFNAME\" is the interface it is\nmonitoring.\n\n\nDeveloper Notes\n===============\n* Files common to ``ifscand`` and ``ifscanctl`` are in the *lib*\n  directory:\n\n    - fastbuf.h: Manage growable buffer of ``uint8_t``\n    - vect.h:  Typesafe vector for \"C\"\n    - error.c: write error message to stderr along with strerror(3)\n      info.\n    - mkdirhier.c: re-entrant, portable mkdir -p implementation in \"C\"\n    - splitargs.c: Separate a quoted string into an array of\n      arguments.\n    - str2hex.c: Convert a string containing hexadecimal characters\n      into equivalent ``uint8_t`` array.\n    - strtrim.c: Remove leading \u0026 trailing white space from a string\n\n* common.h: header file common to ``ifscand`` and ``ifscanctl``.\n\n* Guide to ``ifscand`` sources:\n\n    - ifscand.h: Header file containing all the struct, #defines and\n      function prototypes.\n    - ifscand.c: main() for ifscand and some helper routines.\n    - db.c: Persistent DB storage and retrieval.\n    - ifcfg.c: Configure interface, scan interface etc. \n    - scan.c: Logic to scan for WiFi AP and maintenance post-joining.\n\n\nBUGS, TODO\n==========\n* Sporadic disconnects on iwm(4) when ``ifscand`` runs. I haven't\n  had time to chase this down.\n\n* privilege separation, pledge(2) of ``ifscand``:\n\n   #. one proc to fork/exec external programs\n   #. one proc to ONLY do wifi scan and joins\n   #. one proc to listen to commands from ``ifscanctl``\n\n  Scanning and fork/exec both need root privs. 3) above doesn't in\n  theory need root privs. What does this complexity buy us?\n\n* ``ifscand`` doesn't know when the host wakes up from sleep (zzz, ZZZ).\n  If it had a way to know of this from the kernel, it can scan\n  immediately upon wakeup from sleep.\n\n* ``ifscand`` has no way of asynchronously knowing when RSSI is\n  declining and projected to fade. If the kernel provided this\n  information, ``ifscand`` can avoid the once every 10 second scan.\n\n* ``ifscand`` could remember the BSSID of joined AP and automatically\n  verify if the BSSID changed; and print a warning if it detects a\n  change..?\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopencoff%2Fifscand","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopencoff%2Fifscand","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopencoff%2Fifscand/lists"}