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);
});
});