7

This is probably a very simple thing. I'm new to python so don't crucify me.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, "eth1"+'\0')

the above command gives me:

NameError: name 'IN' is not defined

the only import I have is

import socket
init_js
  • 4,143
  • 2
  • 23
  • 53
user916499
  • 85
  • 1
  • 1
  • 7

4 Answers4

11

If you don't understand the error message, it means you're referring a name IN which is not available at that point. Your code snippet is likely missing an import statement.

The socket module may not offer SO_BINDTODEVICE for portability reasons. If you are absolutely sure that you're running on Linux that supports it, try replacing it with it's numerical value, which is 25:

s.setsockopt(socket.SOL_SOCKET, 25, "eth1"+'\0')

Or for python 3:

s.setsockopt(socket.SOL_SOCKET, 25, str("eth1" + '\0').encode('utf-8'))
TheMeaningfulEngineer
  • 15,679
  • 27
  • 85
  • 143
hamstergene
  • 24,039
  • 5
  • 57
  • 72
  • 1
    I'm used to C and wanted to try doing this in python. Changing my import statement to "import socket, IN" fixed it. – user916499 Aug 28 '11 at 16:12
  • If you're not using the socket module directly you can use monkey patching as described in http://stackoverflow.com/questions/12585317/requests-bind-to-an-ip – Daniel F Nov 07 '13 at 16:16
  • The IN module is standard on linux platforms. It contains most constants from `/usr/include/netinet/in.h`. Sure enough, `SO_BINDTODEVICE` is set to 25 in that file. – init_js Sep 08 '16 at 04:50
  • The '\0' is necessary because the data is likely passed directly to the C API. If the name came from user input, I would also truncate the interface name to IF_NAMESIZE (16 including nul byte): `... , 25, ifname[:16]+'\0')` – init_js Sep 08 '16 at 04:56
3

In Python, SO_BINDTODEVICE is present in IN module. Importing IN will solve the problem.

import socket
import IN

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, "eth0")
rashok
  • 12,790
  • 16
  • 88
  • 100
2

You may even "export" a missing option:

if not hasattr(socket,'SO_BINDTODEVICE') :
    socket.SO_BINDTODEVICE = 25

then

sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, interface+'\0')
jno
  • 997
  • 1
  • 10
  • 18
0

Beware: SO_BINDTODEVICE won't work with packet sockets - Linux man-page man 7 socket

It is not supported for packet sockets (use normal bind(2) there).

Python-Example for eth1 with bind():

rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))
rawSocket.bind(('eth1',0))
Lukas
  • 11
  • 1