Created
April 10, 2018 10:27
-
-
Save wilberforce/cc6025a535b8a4c7e2910d4ba7845f11 to your computer and use it in GitHub Desktop.
Captive Portal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Captive Portal - extending: | |
// https://gist.github.com/MaBecker/ae9dade26b44524e076ca19f5fd72fab | |
// Added form and post back to join network | |
var http = require('http'); | |
var wifi = require('Wifi'); | |
var dgram = require('dgram'); | |
var dns_srv = dgram.createSocket('udp4'); | |
var SSID = 'CaptivePortalTest'; | |
var authMode = 'open'; | |
var password = null; | |
var portHTTP = 80; | |
var portDNS = 53; | |
var dnsIPStr = '192.168.4.1'; | |
var dnsIP = dnsIPStr.split('.').map(n => String.fromCharCode(parseInt(n, 10))).join(''); | |
var page = 'building...'; | |
// get Query name out of message | |
// offset = 12 | |
// end \x00 | |
function dnsQname(msg) { | |
var i = 12; | |
var qname = ''; | |
while ( msg[i] !== '\x00' ) { | |
qname += msg[i]; | |
i++; | |
} | |
console.log({qname:qname}); | |
return qname + '\x00'; | |
} | |
/* | |
1. line header | |
2. line query | |
3. line resource | |
*/ | |
function dnsResponse(msg,dns_ip){ | |
return msg[0]+msg[1] + '\x81\x80'+'\x00\x01'+'\x00\x01'+'\x00\x00\x00\x00' + | |
dnsQname(msg) + '\x00\x01' + '\x00\x01' + | |
'\xc0\x0c'+'\x00\x01'+'\x00\x01'+'\x00\x00\x00\xf9'+'\x00\x04' + dns_ip ; | |
} | |
function startDNSServer(port){ | |
dns_srv .on('error', (err) => { | |
dns_srv.close(); | |
}); | |
dns_srv.on('message', (msg, info) => { | |
// we only serve ip4 | |
if ( msg[msg.length-3] === '\x01') { | |
dns_srv .send(dnsResponse(msg,dnsIP),info.port,info.address); | |
} | |
}); | |
dns_srv.bind(port); | |
} | |
// start http server | |
function startHttpServer(port){ | |
var server = http.createServer(function (req, res) { | |
accept = req.headers.Accept || ''; | |
var a = url.parse(req.url, true); | |
console.log( { accept:accept,a :a } ); | |
if (a.pathname=="/connect") { | |
res.writeHead(200, {'Content-Type': 'text/plain'}); | |
console.log(a.query); | |
wifi.connect(a.query.ssid,{password:a.query.pwd},function(){ | |
console.log("Connected to access point, ",wifi.getIP()); | |
//wifi.save(); | |
// If connect fails - this will not happen... need to handle errors | |
res.end(`connected to ${wifi.getIP().ip}`); | |
}); | |
res.write("Connecting....\n"); | |
} else | |
if (accept !== '*\/*' || a.page === '/hotspot-detect.html' ) { | |
res.writeHead(200, {'Content-Type': 'text/html'}); | |
res.end(page); | |
} else { // redirect to the Setup page | |
res.writeHead(302, {'Location': 'http://192.168.4.1', | |
'Content-Type': 'text/plain'}); | |
res.end(); | |
} | |
}); | |
server.listen(port); | |
} | |
// start being a access point | |
function startAccessPoint(ssid,authMode, password){ | |
wifi.startAP(ssid,{"authMode" : authMode,"password" : password}); | |
} | |
// stop beeing connected to a access point | |
function disconnectStation(){ | |
wifi.disconnect(); | |
} | |
var scan=[]; | |
function start(){ | |
disconnectStation(); | |
startAccessPoint('CaptivePortalTest','open',null); | |
startHttpServer(80); | |
startDNSServer(53); | |
} | |
wifi.scan(function(s){scan=s; | |
scan.map( ap => console.log( ap.ssid ) ); | |
style=` | |
<!----> | |
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/pure/1.0.0/pure-min.css"><style> | |
input{color:inherit;font:inherit;margin:0;} | |
input{line-height:normal;} | |
input::-moz-focus-inner{border:0;padding:0;} | |
.pure-form input[type=email]{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle;box-sizing:border-box;} | |
.pure-form input[type=email]:focus{outline:0;border-color:#129FEA;} | |
.pure-form input:focus:invalid{color:#b94a48;border-color:#e9322d;} | |
.pure-form-aligned input{display:inline-block;vertical-align:middle;} | |
@media only screen and (max-width :480px){ | |
.pure-form input[type=email]{margin-bottom:.3em;display:block;} | |
} | |
html {font-family: sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;} | |
</style>`; | |
page=`<!DOCTYPE html> | |
<title> WiFi</title> | |
<meta name="viewport" content="initial-scale=1.0"> | |
<body> | |
<html> | |
<h1>Captive Hotspot</h1> | |
<form action="/connect" class="pure-form pure-form-aligned"> | |
<fieldset> | |
<div class="pure-control-group"> | |
<label for="Sid">Access Point</label> | |
<select name="ssid">`; | |
scan.map( ap => page+=`<option>${ap.ssid}</option>`); | |
page+=`</select> | |
</div> | |
<div class="pure-control-group"> | |
<label>Password</label> | |
<input name="pwd" type="text" value="espruino"> | |
</div> | |
<div class="pure-controls"> | |
<input type="submit" class="pure-button pure-button-primary" value="Connect"> | |
</div> | |
</fieldset> | |
</form> | |
</html> | |
</body> | |
`; | |
}); | |
setTimeout(start,1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I completed this, take a look at https://gist.github.com/MaBecker/ae9dade26b44524e076ca19f5fd72fab