"[Errno 1]不允许操作"创建套接字时 [英] "[Errno 1] Operation not permitted" when creating socket
问题描述
我正在尝试使用DigiKey针对其Amazon Dash Button hack制作的程序来监视按钮被按下的时间,然后将HTTP GET发送到IFTTT.我正在使用Raspberry Pi来运行它.来源:
I am trying to use the program DigiKey have made for their Amazon Dash Button hack to monitor for when the button is pressed and then send a HTTP GET to IFTTT. I am using a Raspberry Pi to run this. Source:
import socket
import struct
import binascii
import time
import json
import urllib2
# Use your own IFTTT key
ifttt_key = 'example_key'
# Set these up at https://ifttt.com/maker
ifttt_url_button = 'https://maker.ifttt.com/trigger/button_pressed/with/key/' + ifttt_key
# Replace this MAC addresses and nickname with your own
macs = {
'xxxxxxxxxxxx' : 'vanish'
}
# Trigger a IFTTT URL. Body includes JSON with timestamp values.
def trigger_url(url):
data = '{ "value1" : "' + time.strftime("%Y-%m-%d") + '", "value2" : "' + time.strftime("%H:%M") + '" }'
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()
return response
def button_pressed():
print 'triggering button event, response:' + trigger_url(ifttt_url_button)
rawSocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.htons(0x0003))
while True:
packet = rawSocket.recvfrom(2048)
ethernet_header = packet[0][0:14]
ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header)
# skip non-ARP packets
ethertype = ethernet_detailed[2]
if ethertype != '\x08\x06':
continue
# read out data
arp_header = packet[0][14:42]
arp_detailed = struct.unpack("2s2s1s1s2s6s4s6s4s", arp_header)
source_mac = binascii.hexlify(arp_detailed[5])
source_ip = socket.inet_ntoa(arp_detailed[6])
dest_ip = socket.inet_ntoa(arp_detailed[8])
if source_mac in macs:
#print "ARP from " + macs[source_mac] + " with IP " + source_ip
if macs[source_mac] == 'vanish':
button_pressed()
else:
print "Unknown MAC " + source_mac + " from IP " + source_ip
我收到的错误是:
Traceback (most recent call last):
File "/home/pi/Desktop/dash_btn.py", line 30, in <module>
rawSocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.htons(0x0003))
File "/usr/lib/python2.7/socket.py", line 187, in __init__
_sock = _realsocket(family, type, proto)
error: [Errno 1] Operation not permitted
我尝试使用sudo在终端中运行它,但是它没有任何改变.帮助将不胜感激.
I have tried running it in the terminal with sudo , but it hasn't changed anything. Help would be appreciated.
推荐答案
由于您希望接收和解析 ARP 数据包(位于通过AF_INET
接收到的IP级别以下的链路层,OSI层2上),您必须使用低层数据包接口AF_PACKET
.
Since you wish to receive and parse ARP packets (which are on a link layer, OSI layer 2, below IP level you receive with AF_INET
), you'll have to use the low-level packet interface, AF_PACKET
.
从man packet
(对于AF_PACKET
套接字):
对于包含链接级头的原始数据包,套接字类型为
SOCK_RAW
,对于具有以下内容的煮熟数据包,套接字类型为SOCK_DGRAM
链接级标头已删除.链接级头信息以sockaddr_ll
结构的通用格式提供. protocol是网络字节顺序的IEEE 802.3协议编号.有关允许的协议列表,请参见<linux/if_ether.h>
包含文件. 将协议设置为htons(ETH_P_ALL)
时,将接收所有协议.所有传入 该协议类型的数据包在传递到内核中实现的协议之前,将先传递到数据包套接字.
The socket_type is either
SOCK_RAW
for raw packets including the link-level header orSOCK_DGRAM
for cooked packets with the link-level header removed. The link-level header information is available in a common format in asockaddr_ll
structure. protocol is the IEEE 802.3 protocol number in network byte order. See the<linux/if_ether.h>
include file for a list of allowed protocols. When protocol is set tohtons(ETH_P_ALL)
, then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel.
因此,要嗅探ARP数据包,必须使用SOCK_RAW
套接字类型.但是,要使用它,请使用man 7 raw
:
So, for sniffing ARP packets, you must use SOCK_RAW
socket type. However, to use it, from man 7 raw
:
仅允许有效用户ID为0或CAP_NET_RAW功能的进程打开原始套接字.
Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets.
因此,您必须使用sudo
运行程序.
therefore, you'll have to run your program with sudo
.
对于套接字协议(第三个参数),您可以选择现有的0x0003
,这表示ETH_P_ALL
接收所有软件包,或者可能更好,ETH_P_ARP
的值为0x0806
(请参阅您的/usr/include/linux/if_ether.h
)接收仅ARP 软件包.
For socket protocol (third parameter) you might choose 0x0003
as you already have, which means ETH_P_ALL
, receiving all packages, or probably better, ETH_P_ARP
which has a value of 0x0806
(see your /usr/include/linux/if_ether.h
) to receive only ARP packages.
总的来说,这看起来像这样:
All taken together, this looks like this:
rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0806))
while True:
packet = rawSocket.recvfrom(2048)
# no need to filter-out ARP
# less load on user program
这篇关于"[Errno 1]不允许操作"创建套接字时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!