Skip to content

Instantly share code, notes, and snippets.

@wtfaremyinitials
Last active June 19, 2018 03:45
Show Gist options
  • Save wtfaremyinitials/87e35ccb4256983b2e526eb85f92d267 to your computer and use it in GitHub Desktop.
Save wtfaremyinitials/87e35ccb4256983b2e526eb85f92d267 to your computer and use it in GitHub Desktop.

SO_BINDTODEVICE

https://stackoverflow.com/questions/14478167/bind-socket-to-network-interface

You can bind to a specific interface by setting SO_BINDTODEVICE socket option. Warning: You have to be root and have the CAP_NET_RAW capability in order to use this option.

struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0");
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
    ... error handling ...
}
// https://github.com/nodejs/node/issues/3625
var http = require('http'),
    net = require('net'),
    util = require('util'),
    ffi = require('ffi');

var SOL_SOCKET = 1;
var SO_BINDTODEVICE = 25;
var current = ffi.Library(null, {
    'setsockopt': ['int', ['int', 'int', 'int', 'string', 'int']]
});

var remoteIp = "192.168.0.1";
var ourIp = "192.168.0.182";
var ourInterface = "eth1";

function bindingAgent(options) {
    http.Agent.call(this, options);
    this.createConnection = bindingCreateConnection;
}

util.inherits(bindingAgent, http.Agent);

function bindingCreateConnection(port, host, options) {
    var socket;
    socket = new net.Socket({handle: net._createServerHandle(ourIp)});
    var iface = ourInterface;
    var r = current.setsockopt(socket._handle.fd, SOL_SOCKET, SO_BINDTODEVICE, iface, 6);
    if (r === -1)
        throw new Error("getsockopt(SO_BINDTODEVICE) error");

    socket.connect(port, host);

    return socket;
}

var optionsAgent = {};
var ourBindingAgent = new bindingAgent(optionsAgent);

var httpReq = {};
httpReq.port = 80;
httpReq.host = remoteIp;
httpReq.path = '/index.html';
httpReq.headers = {'Referer': 'http://' + remoteIp + ':' + httpReq.port + '/index.html'};
httpReq.agent = ourBindingAgent;

var body = '';
var creq = http.get(httpReq);
creq.on('response', function (res) {
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
        console.log(chunk);
    });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment