title: ICMP pinger application in Python - error: operation not permitted?
body: <p>I am trying to run this ICMP pinger application (Python 2.7). It is giving me this error message.</p>
  
  <p><strong>Traceback (most recent call last):
    line 125, in 
      ping("www.poly.edu")
    line 120, in ping
      delay = doOnePing(dest, timeout)
    line 104, in doOnePing
      raise socket.error(msg)
  error: Operation not permitted</strong>    </p>
  
  <p>I am not sure what is wrong. Is there something wrong with the code? Or is the code correct and the function is not permitted for other reason? </p>
  
  <pre><code>from socket import *
  import os
  import sys
  import struct
  import time
  import select
  import binascii
  import socket
  
  ICMP_ECHO_REQUEST = 8
  timeRTT = []
  packageSent =0;
  packageRev = 0;
  
  def checksum(str):
      csum = 0
      countTo = (len(str) / 2) * 2
      count = 0
      while count &lt; countTo:
          thisVal = ord(str[count+1]) * 256 + ord(str[count])
          csum = csum + thisVal
          csum = csum &amp; 0xffffffffL
          count = count + 2
      if countTo &lt; len(str):
          csum = csum + ord(str[len(str) - 1])
          csum = csum &amp; 0xffffffffL
      csum = (csum &gt;&gt; 16) + (csum &amp; 0xffff)
      csum = csum + (csum &gt;&gt; 16)
      answer = ~csum
      answer = answer &amp; 0xffff
      answer = answer &gt;&gt; 8 | (answer &lt;&lt; 8 &amp; 0xff00)
      return answer
  
  def receiveOnePing(mySocket, ID, timeout, destAddr):
      global packageRev,timeRTT
      timeLeft = timeout
      while 1:
          startedSelect = time.time()
          whatReady = select.select([mySocket], [], [], timeLeft)
          howLongInSelect = (time.time() - startedSelect)
          if whatReady[0] == []: # Timeout
              return "0: Destination Network Unreachable,"
          timeReceived = time.time()
          recPacket, addr = mySocket.recvfrom(1024)
  
      #Fill in start
          #Fetch the ICMP header from the IP packet
          icmpHeader = recPacket[20:28]
          requestType, code, revChecksum, revId, revSequence = struct.unpack('bbHHh',icmpHeader)
          if ID == revId:
              bytesInDouble = struct.calcsize('d')
              #struct.calcsize(fmt) Return the size of the struct (and hence of the string) corresponding to the given format.
          #struct.unpack(fmt, buffer[, offset=0]) Unpack the buffer according to the given format. The result is a tuple even if it contains exactly one item. The buffer must contain at least the amount of data required by the format (len(buffer[offset:]) must be at least calcsize(fmt)).
              timeData = struct.unpack('d',recPacket[28:28 + bytesInDouble])[0] 
              timeRTT.append(timeReceived - timeData)
              packageRev += 1
              return timeReceived - timeData
          else:
              return "ID does not match"
          #Fill in end
  
          timeLeft = timeLeft - howLongInSelect
          if timeLeft &lt;= 0:
              return "1: Request timed out."
  
  def sendOnePing(mySocket, destAddr, ID):
      global packageSent
      # Header is type (8), code (8), checksum (16), id (16), sequence (16)
  
      myChecksum = 0
      # Make a dummy header with a 0 checksum.
      # struct -- Interpret strings as packed binary data
      header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
      data = struct.pack("d", time.time())
      # Calculate the checksum on the data and the dummy header.
      myChecksum = checksum(header + data)
  
      # Get the right checksum, and put in the header
      if sys.platform == 'darwin':
          myChecksum = socket.htons(myChecksum) &amp; 0xffff
          #Convert 16-bit integers from host to network byte order.
      else:
          myChecksum = socket.htons(myChecksum)
  
      header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
      packet = header + data
  
      mySocket.sendto(packet, (destAddr, 1))
      packageSent += 1
      # AF_INET address must be tuple, not str
      #Both LISTS and TUPLES consist of a number of objects
      #which can be referenced by their position number within the object
  
  def doOnePing(destAddr, timeout):
      icmp = socket.getprotobyname("icmp")
      #SOCK_RAW is a powerful socket type. For more details see:http://sock-raw.org/papers/sock_raw
  
      #Fill in start
      #Create Socket here
      try:
          mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
      except socket.error, (errno, msg):
          if errno == 1:
              raise socket.error(msg)
      #Fill in end
  
      myID = os.getpid() &amp; 0xFFFF  #Return the current process i
      sendOnePing(mySocket, destAddr, myID)
      delay = receiveOnePing(mySocket, myID, timeout, destAddr)
      mySocket.close()
      return delay
  
  def ping(host, timeout=1):
      #timeout=1 means: If one second goes by without a reply from the server,
      dest = socket.gethostbyname(host)
      print "Pinging " + dest + " using Python:"
      print ""
      #Send ping requests to a server separated by approximately one second
      while 1 :
          delay = doOnePing(dest, timeout)
          print "RTT:",delay
          time.sleep(1)# one second
      return delay
  
  ping("www.poly.edu")
  </code></pre>