本文介绍了"[Errno 1]不允许操作"创建套接字时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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套接字):

因此,要嗅探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:

因此,您必须使用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]不允许操作"创建套接字时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 02:54
查看更多