“[Errno 1] Operation not permitted” when creating socket

本小妞迷上赌 提交于 2019-12-24 07:46:05

问题


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 

The error I receive is:

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

I have tried running it in the terminal with sudo , but it hasn't changed anything. Help would be appreciated.


回答1:


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.

From man packet (for AF_PACKET sockets):

The socket_type is either SOCK_RAW for raw packets including the link-level header or SOCK_DGRAM for cooked packets with the link-level header removed. The link-level header information is available in a common format in a sockaddr_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 to htons(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.

So, for sniffing ARP packets, you must use SOCK_RAW socket type. However, to use it, from man 7 raw:

Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets.

therefore, you'll have to run your program with sudo.

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


来源:https://stackoverflow.com/questions/45127645/errno-1-operation-not-permitted-when-creating-socket

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!