5

I have a UDP connection up and listening on a port (localhost) and I am trying to send a Scapy packet from localhost as well. For some reason, my C code never actually captures the packet, however I can see the packet show up in Wireshark just fine. It's been awhile since I've used sockets, but is there some special socket options I have to set or why would I be able to see the packet in Wireshark just fine but not by the C socket?

Note: I was able to successfully catch a packet when I wrote corresponding socket code to send out packets (from localhost) however I am still unable to get the listening code to catch the packet when sent from another computer.

I have found a similar question but when I tried their approach (using UDP instead of TCP), I still couldn't get netcat to catch the Scapy packet.

C Code (condensed for clarity sake)

int main() {
    int sock, dataLen, inLen;
    struct sockaddr_in inAddr;
    short listen_port = 8080;
    char buffer[2048];

    if (sock = socket(AF_INET,SOCK_DGRAM,0) < 0) {
        printf("ERROR: unable to establish socket\n");
    return -1;
    }

    // zero out address structure
    memset(&inAddr, 0, sizeof(inAddr));

    inAddr.sin_family = AF_INET;
    inAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    inAddr.sin_port = htons(listen_port);

    if (bind(sock, (struct sockaddr*)&inAddr, sizeof(inAddr)) < 0) {
    printf("ERROR: unable to bind\n");
    return -1;
    }

    inLen = sizeof(inAddr);

    printf("Now listening on port %d\n", listen_port);
    while(1) {
    dataLen = recvfrom(sock, buffer, 1500, 0, (struct sockaddr*)&inAddr, &inLen);

    if (dataLen < 0)
        printf("Error receiving datagram\n");
    else
        printf("Received packet of length %d\n", dataLen);

    }
    return 0;
}

Scapy Script

# set interface
conf.iface="lo0"

# create IP packet
ip_pkt = IP()/UDP()
ip_pkt.payload = "payload test message"
ip_pkt.dport = 8080
ip_pkt.dst = "127.0.0.1"
ip_pkt.src = "127.0.0.1"

# send out packet
send(ip_pkt)
Community
  • 1
  • 1
Josh Bradley
  • 4,630
  • 13
  • 54
  • 79
  • Your listener on the localhost will never be able to capture packets sent from another computer, since those packets will not traverse the loopback interface of your listener. – jxh Jul 16 '13 at 22:34
  • @jxh Listener is bound to `INADDR_ANY`; it depends on the system but sending packets to 127.0.0.1 from another address may get filtered – bbonev Jul 17 '13 at 01:05
  • @bbonev: The `Scapy Script` specifies destination IP of localhost. If that script is running on a different machine, there is no way for it to arrive on the listener's machine. – jxh Jul 17 '13 at 01:07
  • @jxh Yes, the problem is in the client, not the server. BTW even on the same machine the set of dest ip 127.0.0.1 and interface eth0 may not work – bbonev Jul 17 '13 at 01:13
  • You should not be able to send to `127.0.0.1` from any address thats not in the `127.0.0.0/8` mask. – Havenard Jul 17 '13 at 03:49
  • You can assume that there is no outside network. Just the loopback interface. I modified the source and destination of the scapy packet, but my C program is still not catching the packet. As far as using INADDR_ANY is concerned, I believe it should still work. I thought INADDR_ANY captured on all interfaces. – Josh Bradley Jul 17 '13 at 06:10

3 Answers3

8

Scapy needs to be configured slightly differently to work on the Loopback interface, see http://www.secdev.org/projects/scapy/doc/troubleshooting.html under the heading "I can’t ping 127.0.0.1. Scapy does not work with 127.0.0.1 or on the loopback interface"

I used the code given there and sent a scapy packet which was received by a C Socket, this was specifically:

from scapy.all import *
conf.L3socket=L3RawSocket
packet=IP()/UDP(dport=32000)/"HELLO WORLD"
send(packet)

This was then received on a UDP C Socket bound to lo on port 32000 (Scapy defaults to sending IP packets over the loopback interface).

Eosis
  • 548
  • 1
  • 4
  • 12
2

I have the same problem, udp socket does not receive scapy packet. I suppose there might be something related to this post: Raw Socket Help: Why UDP packets created by raw sockets are not being received by kernel UDP? And what works for me is the socket.IP_HDRINCL option. Here is the working code for both and sender.

sender:

import socket
from scapy.all import *

rawudp=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
rawudp.bind(('0.0.0.0',56789))
rawudp.setsockopt(socket.SOL_IP, socket.IP_HDRINCL,1)

pkt = IP()/UDP(sport=56789, dport=7890)/'hello'

rawudp.sendto(pkt.build(), ('127.0.0.1',7890))

receiver:

import socket
so = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
so.bind(('0.0.0.0',7890))
while True:
    print so.recv(1024)

Verified on Fedora 14, although doesn't work on my MBP...

Community
  • 1
  • 1
赵伟辰
  • 43
  • 6
1

I think the problem is in setting incompatible set of interface, src and dst address.

When destination is loopback (127.0.0.1), interface should be lo and addresses (assuming both client and server run on the same host):

ip_pkt.dst = "127.0.0.1"
ip_pkt.src = "127.0.0.1"

Another way is to send to the ethernet address (assuming 192.168.1.1 is configured on eth0 and both client and server run on the same host):

ip_pkt.dst = "192.168.1.1"
ip_pkt.src = "192.168.1.1"

If you try different hosts, then using 127.0.0.1 and lo is not possible. Set src to client machine's ip and dst to server machine's ip.

bbonev
  • 1,406
  • 2
  • 16
  • 33
  • Should it really matter what the src IP is in the scapy script? I mean, you can spoof the src IP to something besides the real IP and Scapy will send out the packet just fine to another computer (I've done it before). – Josh Bradley Jul 17 '13 at 03:29
  • Depends on configuration - receiver machine may reject packets with unexpected source. Can you clarify your networking setup? – bbonev Jul 17 '13 at 03:44
  • It has nothing to do with Scapy, it has to do with basic IP networking stuff. The interface `127.0.0.0/8` is localhost only, it doesn't even use or require a network card to exist, and you cannot send stuff to it from any other network. Its even a security matter. Even if this packet is hitting its target machine, the system will drop this packet simply because it cannot be addressed to this network if its not coming from it aswell. – Havenard Jul 17 '13 at 03:51