Pcap Error Codes Error codes for the pcap API. These will all be negative, so you can check for the success or failure of a call that returns these codes by checking for a negative value.
Value to pass to pcap_compile() as the netmask if you don't know what the netmask is.
Warning codes for the pcap API. These will all be positive and non-zero, so they won't look like errors.
Return the name of a network device on the system.
The pcap_lookupdev subroutine gets a network device suitable for use with the pcap_open_live and the pcap_lookupnet subroutines. If no interface can be found, or none are configured to be up, Null is returned. In the case of multiple network devices attached to the system, the pcap_lookupdev subroutine returns the first one it finds to be up, other than the loopback interface. (Loopback is always ignored.)
static VALUE rbpcap_s_lookupdev(VALUE self) { char *dev = NULL; char eb[PCAP_ERRBUF_SIZE]; VALUE ret_dev; /* device string to return */ #if defined(WIN32) /* pcap_lookupdev is broken on windows */ pcap_if_t *alldevs; pcap_if_t *d; /* Retrieve the device list from the local machine */ if (pcap_findalldevs(&alldevs,eb) == -1) { rb_raise(eBindingError,"%s",eb); } /* Find the first interface with an address and not loopback */ for(d = alldevs; d != NULL; d= d->next) { if(d->name && d->addresses && !(d->flags & PCAP_IF_LOOPBACK)) { dev=d->name; break; } } if (dev == NULL) { rb_raise(eBindingError,"%s","No valid interfaces found, Make sure WinPcap is installed.\n"); } ret_dev = rb_str_new2(dev); /* We don't need any more the device list. Free it */ pcap_freealldevs(alldevs); #else dev = pcap_lookupdev(eb); if (dev == NULL) { rb_raise(eBindingError, "%s", eb); } ret_dev = rb_str_new2(dev); #endif return ret_dev; }
Returns the network address and subnet mask for a network device.
static VALUE rbpcap_s_lookupnet(VALUE self, VALUE dev) { bpf_u_int32 net, mask, m; struct in_addr addr; char eb[PCAP_ERRBUF_SIZE]; VALUE list; Check_Type(dev, T_STRING); if (pcap_lookupnet(StringValuePtr(dev), &net, &mask, eb) == -1) { rb_raise(rb_eRuntimeError, "%s", eb); } addr.s_addr = net; m = ntohl(mask); list = rb_ary_new(); rb_ary_push(list, rb_str_new2((char *) inet_ntoa(addr))); rb_ary_push(list, UINT2NUM(m)); return(list); }
Creates a new Pcap instance and returns the object itself.
static VALUE rbpcap_new_s(VALUE class) { VALUE self; rbpcap_t *rbp; // need to make destructor do a pcap_close later self = Data_Make_Struct(class, rbpcap_t, 0, rbpcap_free, rbp); rb_obj_call_init(self, 0, 0); memset(rbp, 0, sizeof(rbpcap_t)); return self; }
open a fake Pcap for compiling filters or opening a capture for output
::Pcap.open_dead() is used for creating a pcap structure to use when calling the other functions like compiling BPF code.
linktype specifies the link-layer type
snaplen specifies the snapshot length
Returns the object itself.
static VALUE rbpcap_open_dead_s(VALUE class, VALUE linktype, VALUE snaplen) { VALUE iPcap = rb_funcall(rb_cPcap, rb_intern("new"), 0); return rbpcap_open_dead(iPcap, linktype, snaplen); }
capture = ::Pcap.open_live(@dev, @snaplength, @promiscous_mode, @timeout)
Returns the object itself.
static VALUE rbpcap_open_live_s(VALUE class, VALUE iface, VALUE snaplen, VALUE promisc, VALUE timeout) { VALUE iPcap = rb_funcall(rb_cPcap, rb_intern("new"), 0); return rbpcap_open_live(iPcap, iface, snaplen, promisc, timeout); }
Returns the integer datalink value unless capture
foo.bar unless capture.datalink == Pcap::DLT_EN10MB
static VALUE rbpcap_datalink(VALUE self) { rbpcap_t *rbp; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; return INT2NUM(pcap_datalink(rbp->pd)); }
not sure if this deviates too much from the way the rest of this class works?
Writes packet capture date to a binary file assigned with dump_open().
Returns the object itself.
static VALUE rbpcap_dump(VALUE self, VALUE caplen, VALUE pktlen, VALUE packet) { rbpcap_t *rbp; struct pcap_pkthdr pcap_hdr; if(TYPE(packet) != T_STRING) rb_raise(rb_eArgError, "packet data must be a string"); if(TYPE(caplen) != T_FIXNUM) rb_raise(rb_eArgError, "caplen must be a fixnum"); if(TYPE(pktlen) != T_FIXNUM) rb_raise(rb_eArgError, "pktlen must be a fixnum"); Data_Get_Struct(self, rbpcap_t, rbp); gettimeofday(&pcap_hdr.ts, NULL); pcap_hdr.caplen = NUM2UINT(caplen); pcap_hdr.len = NUM2UINT(pktlen); //capture.next is yeilding an 8Bit ASCII string // -> return rb_str_new((char *) job.pkt, job.hdr.caplen); //Call dump such that capture.next{|pk| capture.dump(pk.length, pk.length, pk)} pcap_dump( (u_char*)rbp->pdt, &pcap_hdr, (unsigned char *)RSTRING_PTR(packet) ); return self; }
dump_close() is called to manually close a "savefile"
static VALUE rbpcap_dump_close(VALUE self) { rbpcap_t *rbp; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; if(!rbp->pdt) rb_raise(eDumperError, "Stream is already closed."); if (rbp->pdt) pcap_dump_close(rbp->pdt); rbp->pdt = NULL; return self; }
dump_open() is called to open a "savefile" for writing
static VALUE rbpcap_dump_open(VALUE self, VALUE filename) { rbpcap_t *rbp; if(TYPE(filename) != T_STRING) rb_raise(rb_eArgError, "filename must be a string"); Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; rbp->pdt = pcap_dump_open( rbp->pd, RSTRING_PTR(filename) ); if(!rbp->pdt) rb_raise(eDumperError, "Stream could not be initialized or opened."); return self; }
Alias of each_data
static VALUE rbpcap_each_data(VALUE self) { rbpcap_t *rbp; int fno = -1; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; #if !defined(WIN32) fno = pcap_get_selectable_fd(rbp->pd); #else fno = pcap_fileno(rbp->pd); #endif for(;;) { VALUE packet = rbpcap_next_data(self); if(packet == Qnil && rbp->type == OFFLINE) break; packet == Qnil ? rb_thread_wait_fd(fno) : rb_yield(packet); } return self; }
Yields each packet from the capture to the passed-in block in turn.
static VALUE rbpcap_each_data(VALUE self) { rbpcap_t *rbp; int fno = -1; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; #if !defined(WIN32) fno = pcap_get_selectable_fd(rbp->pd); #else fno = pcap_fileno(rbp->pd); #endif for(;;) { VALUE packet = rbpcap_next_data(self); if(packet == Qnil && rbp->type == OFFLINE) break; packet == Qnil ? rb_thread_wait_fd(fno) : rb_yield(packet); } return self; }
Yields a PCAP::Packet from the capture to the passed-in block in turn.
static VALUE rbpcap_each_packet(VALUE self) { rbpcap_t *rbp; int fno = -1; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; #if !defined(WIN32) fno = pcap_get_selectable_fd(rbp->pd); #else fno = pcap_fileno(rbp->pd); #endif for(;;) { VALUE packet = rbpcap_next_packet(self); if(packet == Qnil && rbp->type == OFFLINE) break; packet == Qnil ? rb_thread_wait_fd(fno) : rb_yield(packet); } return self; }
inject() transmit a raw packet through the network interface
Returns the number of bytes written on success else raise failure.
static VALUE rbpcap_inject(VALUE self, VALUE payload) { rbpcap_t *rbp; if(TYPE(payload) != T_STRING) rb_raise(rb_eArgError, "payload must be a string"); Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; #if defined(WIN32) /* WinPcap does not have a pcap_inject call we use pcap_sendpacket, if it suceedes * we simply return the amount of packets request to inject, else we fail. */ if(pcap_sendpacket(rbp->pd, RSTRING_PTR(payload), RSTRING_LEN(payload)) != 0) { rb_raise(rb_eRuntimeError, "%s", pcap_geterr(rbp->pd)); } return INT2NUM(RSTRING_LEN(payload)); #else return INT2NUM(pcap_inject(rbp->pd, RSTRING_PTR(payload), RSTRING_LEN(payload))); #endif }
Alias of next_data
static VALUE rbpcap_next_data(VALUE self) { rbpcap_t *rbp; rbpcapjob_t job; char eb[PCAP_ERRBUF_SIZE]; int ret; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; pcap_setnonblock(rbp->pd, 1, eb); #ifdef MAKE_TRAP TRAP_BEG; #endif // ret will contain the number of packets captured during the trap (ie one) since this is an iterator. ret = pcap_dispatch(rbp->pd, 1, (pcap_handler) rbpcap_handler, (u_char *)&job); #ifdef MAKE_TRAP TRAP_END; #endif if(rbp->type == OFFLINE && ret <= 0) return Qnil; if(ret > 0 && job.hdr.caplen > 0) return rb_str_new((char *) job.pkt, job.hdr.caplen); return Qnil; }
*
Returns the next packet from the packet capture device. Returns a string with the packet data. If the next_data() is unsuccessful, Null is returned.
static VALUE rbpcap_next_data(VALUE self) { rbpcap_t *rbp; rbpcapjob_t job; char eb[PCAP_ERRBUF_SIZE]; int ret; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; pcap_setnonblock(rbp->pd, 1, eb); #ifdef MAKE_TRAP TRAP_BEG; #endif // ret will contain the number of packets captured during the trap (ie one) since this is an iterator. ret = pcap_dispatch(rbp->pd, 1, (pcap_handler) rbpcap_handler, (u_char *)&job); #ifdef MAKE_TRAP TRAP_END; #endif if(rbp->type == OFFLINE && ret <= 0) return Qnil; if(ret > 0 && job.hdr.caplen > 0) return rb_str_new((char *) job.pkt, job.hdr.caplen); return Qnil; }
Returns the next packet from the packet capture device.
Returns a string with the packet data.
If the next_packet() is unsuccessful, Null is returned.
static VALUE rbpcap_next_packet(VALUE self) { rbpcap_t *rbp; rbpcapjob_t job; char eb[PCAP_ERRBUF_SIZE]; int ret; rbpacket_t* rbpacket; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; pcap_setnonblock(rbp->pd, 1, eb); #ifdef MAKE_TRAP TRAP_BEG; #endif ret = pcap_dispatch(rbp->pd, 1, (pcap_handler) rbpcap_handler, (u_char *)&job); #ifdef MAKE_TRAP TRAP_END; #endif if(rbp->type == OFFLINE && ret <= 0) return Qnil; if(ret > 0 && job.hdr.caplen > 0) { rbpacket = ALLOC(rbpacket_t); rbpacket->hdr = &job.hdr; rbpacket->pkt = (u_char *)&job.pkt; return Data_Wrap_Struct(rb_cPkt, 0, rbpacket_free, rbpacket); } return Qnil; }
Returns the integer PCAP MAJOR LIBRARY value unless capture
static VALUE rbpcap_major_version(VALUE self) { rbpcap_t *rbp; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; return INT2NUM(pcap_major_version(rbp->pd)); }
Returns the integer PCAP MINOR LIBRARY value unless capture
static VALUE rbpcap_minor_version(VALUE self) { rbpcap_t *rbp; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; return INT2NUM(pcap_minor_version(rbp->pd)); }
Provide a valid bpf-filter to apply to the packet capture
# Show me all SYN packets: bpf-filter = "tcp[13] & 2 != 0" capture.setfilter(bpf-filter)
Examples:
"net 10.0.0.0/8"
"not tcp and dst host 192.168.1.1"
Returns the object itself.
static VALUE rbpcap_setfilter(VALUE self, VALUE filter) { char eb[PCAP_ERRBUF_SIZE]; rbpcap_t *rbp; u_int32_t mask = 0, netid = 0; struct bpf_program bpf; Data_Get_Struct(self, rbpcap_t, rbp); if(TYPE(filter) != T_STRING) rb_raise(eBPFilterError, "filter must be a string"); if(! rbpcap_ready(rbp)) return self; if(rbp->type == LIVE) if(pcap_lookupnet(rbp->iface, &netid, &mask, eb) < 0) { netid = 0; mask = 0; rb_warn("unable to get IP: %s", eb); } if(pcap_compile(rbp->pd, &bpf, RSTRING_PTR(filter), 0, mask) < 0) rb_raise(eBPFilterError, "invalid bpf filter"); if(pcap_setfilter(rbp->pd, &bpf) < 0) rb_raise(eBPFilterError, "unable to set bpf filter"); return self; }
Alias of snapshot
static VALUE rbpcap_snapshot(VALUE self) { rbpcap_t *rbp; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; return INT2NUM(pcap_snapshot(rbp->pd)); }
Returns the snapshot length, which is the number of bytes to save for each packet captured.
static VALUE rbpcap_snapshot(VALUE self) { rbpcap_t *rbp; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; return INT2NUM(pcap_snapshot(rbp->pd)); }
Returns a hash with statistics of the packet capture
# number of packets received
# number of packets dropped
# number of packets dropped by interface
static VALUE rbpcap_stats(VALUE self) { rbpcap_t *rbp; struct pcap_stat stat; VALUE hash; Data_Get_Struct(self, rbpcap_t, rbp); if(! rbpcap_ready(rbp)) return self; if (pcap_stats(rbp->pd, &stat) == -1) return Qnil; hash = rb_hash_new(); rb_hash_aset(hash, rb_str_new2("recv"), UINT2NUM(stat.ps_recv)); rb_hash_aset(hash, rb_str_new2("drop"), UINT2NUM(stat.ps_drop)); rb_hash_aset(hash, rb_str_new2("idrop"), UINT2NUM(stat.ps_ifdrop)); // drops by interface XXX not yet supported under pcap.h 2.4 //#if defined(WIN32) // rb_hash_aset(hash, rb_str_new2("bs_capt"), UINT2NUM(stat.bs_capt)); //#endif return hash; }
Generated with the Darkfish Rdoc Generator 2.