Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

immediate os error in osx and linux platform #12

Closed
yangbh opened this issue Sep 22, 2015 · 6 comments
Closed

immediate os error in osx and linux platform #12

yangbh opened this issue Sep 22, 2015 · 6 comments

Comments

@yangbh
Copy link

yangbh commented Sep 22, 2015

pypcap v1.1.4

in mac osx, if i set immediate=False, can not sniff any packet
if i set immediate=True, my code works right

in linux, if i set immediate=True, it will throws this execption
File "/root/work/pytscan/pytscan/scan.py", line 735, in pypcapParse
pc = pcap.pcap(name=self.iface,immediate=True)
File "pcap.pyx", line 210, in pcap.pcap.init (pcap.c:1773)
OSError: couldn't enable immediate mode

thank you, guys

@brifordwylie
Copy link
Contributor

@yangbh so this code seems to work fine for me on OSX

import pcap

print 'Opening interface...'
pc = pcap.pcap(promisc=True)
for timestamp, packet in pc: 
    print 'Packet...', repr(packet)

On OSX, if I set immediate=True obviously I get packets right away.. if I don't I have to wait about 45 seconds and then stuff starts spitting out.. I think because I don't see that much traffic on my home network.

On Linux I have to do some defensive coding.. as you often can't get immediate mode...

            try:
                self.pcap = pcap.pcap(name=self.iface_name, promisc=True, immediate=True)
            except OSError:
                try:
                    logging.warning('Could not get immediate mode, turning flag off')
                    self.pcap = pcap.pcap(name=self.iface_name, promisc=True, immediate=False)

The above code is pulled from https://github.com/SuperCowPowers/chains

@yangbh
Copy link
Author

yangbh commented Dec 27, 2015

@brifordwylie 3ks for answer
Your code works fin, but here is another problem.

On Linux, if set immediate=False, pcap.loop() will exit if there is no packet in a few seconds, so i must restart pcap.loop(), but this causes packet loss.
Here is my code:

def startloop(timestamp,pkt):
    eth=dpkt.ethernet.Ethernet(pkt)
print eth
        while True:
            try:
                pc.loop(0, startloop)
                nrecv,ndrop,nifdrop=pc.stats()
                logging.warning('%s, %s, %s' % (nrecv,ndrop,nifdrop))
            except Exception,e:
                logging.error(str(e))

Do you have any good idea? Thanks very much.

@hellais
Copy link
Member

hellais commented Apr 18, 2016

@yangbh can you check to see if the fix introduce in PR#15 addresses the issues you had?

It will be included inside of a new release of pypcap.

@yangbh
Copy link
Author

yangbh commented Apr 22, 2016

@hellais yes, it works fine now, thanks very much

@hellais
Copy link
Member

hellais commented Apr 22, 2016

@yangbh excellent. I will make a new release of pypcap today then.

@hellais hellais closed this as completed Apr 22, 2016
@guyharris
Copy link
Collaborator

guyharris commented Jul 1, 2016

There's no guarantee that you can set immediate mode after you've opened a capture device; it doesn't work on Linux systems using TPACKET_V3 (which will be the case with newer kernels and newer versions of libpcap).

If libpcap has pcap_set_immediate_mode() - which means it also has pcap_create() and pcap_activate() - you can, at open time, set immediate mode by doing:

pcap_t *p;
char errbuf[PCAP_ERRBUF_SIZE];
int status;

p = pcap_create(<device name>, errbuf);
if (p == NULL) {
    /* the attempt failed; errbuf has the error message */
}
pcap_set_timeout(p, <the timeout value>);
pcap_set_snaplen(p, <the snapshot length>);
if (you want immediate mode)
    pcap_set_immediate_mode(p, 1);
status = pcap_activate(p);
if (status < 0) {
    /* the attempt failed */
    if (status == PCAP_ERROR)
        /* pcap_geterr(p) returns an error message */
    else {
        /* pcap_statustostr(p) returns an error message */
        if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
            status == PCAP_ERROR_PERM_DENIED) {
            /* pcap_geterr(p) gives more details, if the string it returns isn't a null string */
        }
    }
}

This works on all UN*Xes, and works on Windows if you have a version of WinPcap/Npcap that supports pcap_set_immediate_mode() (current versions of WinPcap don't).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants