Skip to content

Commit

Permalink
Merge pull request #28 from darrenw/initial
Browse files Browse the repository at this point in the history
Tweak to the IPv6 address zero-compression function
  • Loading branch information
mranney committed Jan 15, 2012
2 parents 8221090 + 62eb9cd commit f0c04a5
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 33 deletions.
37 changes: 29 additions & 8 deletions pcap.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -171,16 +171,37 @@ var unpack = {
].join('.'); ].join('.');
}, },
ipv6_addr: function (raw_packet, offset) { ipv6_addr: function (raw_packet, offset) {
var ret = ''; var ret = '';
for (var i=offset; i<offset+16; i+=2) { var octets = [];
if (i > offset) { for (var i=offset; i<offset+16; i+=2) {
ret += ':'; octets.push(unpack.uint16(raw_packet,i).toString(16));
}
var curr_start, curr_len = undefined;
var max_start, max_len = undefined;
for(var i = 0; i < 8; i++){
if(octets[i] == "0"){
if(curr_start === undefined){
curr_len = 1;
curr_start = i;
}else{
curr_len++;
if(!max_start || curr_len > max_len){
max_start = curr_start;
max_len = curr_len;
} }
ret += unpack.uint16(raw_packet, i).toString(16); }
}else{
curr_start = undefined;
} }
// TODO: do a better job to compress out largest run of zeros. }
return ret.replace(/(0:)+/, ':');
return ret; if(max_start !== undefined){
var tosplice = max_start == 0 || (max_start + max_len > 7) ? ":" : "";
octets.splice(max_start, max_len,tosplice);
if(max_len == 8){octets.push("");}
}
ret = octets.join(":");
return ret;
} }
}; };
exports.unpack = unpack; exports.unpack = unpack;
Expand Down
63 changes: 38 additions & 25 deletions pcap_binding.cc
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -200,13 +200,15 @@ Open(bool live, const Arguments& args)
return ThrowException(Exception::Error(String::New(errbuf))); return ThrowException(Exception::Error(String::New(errbuf)));
} }


// TODO - if filter is empty, don't bother with compile or set if(filter.length() != 0){
if (pcap_compile(pcap_handle, &fp, (char *) *filter, 1, net) == -1) { if (pcap_compile(pcap_handle, &fp, (char *) *filter, 1, net) == -1) {
return ThrowException(Exception::Error(String::New(pcap_geterr(pcap_handle)))); return ThrowException(Exception::Error(String::New(pcap_geterr(pcap_handle))));
} }

if (pcap_setfilter(pcap_handle, &fp) == -1) { if (pcap_setfilter(pcap_handle, &fp) == -1) {
return ThrowException(Exception::Error(String::New(pcap_geterr(pcap_handle)))); return ThrowException(Exception::Error(String::New(pcap_geterr(pcap_handle))));
}
pcap_freecode(&fp);
} }


// Work around buffering bug in BPF on OSX 10.6 as of May 19, 2010 // Work around buffering bug in BPF on OSX 10.6 as of May 19, 2010
Expand Down Expand Up @@ -256,6 +258,27 @@ OpenOffline(const Arguments& args)
return Open(false, args); return Open(false, args);
} }


// Helper method, convert a sockaddr* (AF_INET or AF_INET6) to a string, and set it as the property
// named 'key' in the Address object you pass in.
void SetAddrStringHelper(const char* key, sockaddr *addr, Local<Object> Address){
if(key && addr){
char dst_addr[INET6_ADDRSTRLEN + 1] = {0};
char* src = 0;
socklen_t size = 0;
if(addr->sa_family == AF_INET){
struct sockaddr_in* saddr = (struct sockaddr_in*) addr;
src = (char*) &(saddr->sin_addr);
size = INET_ADDRSTRLEN;
}else{
struct sockaddr_in6* saddr6 = (struct sockaddr_in6*) addr;
src = (char*) &(saddr6->sin6_addr);
size = INET6_ADDRSTRLEN;
}
const char* address = inet_ntop(addr->sa_family, src, dst_addr, size);
Address->Set(String::New(key), String::New(address));
}
}

Handle<Value> Handle<Value>
FindAllDevs(const Arguments& args) FindAllDevs(const Arguments& args)
{ {
Expand All @@ -280,27 +303,17 @@ FindAllDevs(const Arguments& args)
Local<Array> AddrArray = Array::New(); Local<Array> AddrArray = Array::New();
int j = 0; int j = 0;
for (pcap_addr_t *cur_addr = cur_dev->addresses ; cur_addr != NULL ; cur_addr = cur_addr->next, j++) { for (pcap_addr_t *cur_addr = cur_dev->addresses ; cur_addr != NULL ; cur_addr = cur_addr->next, j++) {
if (cur_addr->addr && cur_addr->addr->sa_family == AF_INET) { if (cur_addr->addr){
Local<Object> Address = Object::New(); int af = cur_addr->addr->sa_family;

if(af == AF_INET || af == AF_INET6){
struct sockaddr_in *sin = (struct sockaddr_in *) cur_addr->addr; Local<Object> Address = Object::New();
Address->Set(String::New("addr"), String::New(inet_ntoa(sin->sin_addr))); SetAddrStringHelper("addr", cur_addr->addr, Address);

SetAddrStringHelper("netmask", cur_addr->netmask, Address);
if (cur_addr->netmask != NULL) { SetAddrStringHelper("broadaddr", cur_addr->broadaddr, Address);
sin = (struct sockaddr_in *) cur_addr->netmask; SetAddrStringHelper("dstaddr", cur_addr->dstaddr, Address);
Address->Set(String::New("netmask"), String::New(inet_ntoa(sin->sin_addr))); AddrArray->Set(Integer::New(j), Address);
} }
if (cur_addr->broadaddr != NULL) {
sin = (struct sockaddr_in *) cur_addr->broadaddr;
Address->Set(String::New("broadaddr"), String::New(inet_ntoa(sin->sin_addr)));
}
if (cur_addr->dstaddr != NULL) {
sin = (struct sockaddr_in *) cur_addr->dstaddr;
Address->Set(String::New("dstaddr"), String::New(inet_ntoa(sin->sin_addr)));
}
AddrArray->Set(Integer::New(j), Address);
} }
// TODO - support AF_INET6
} }


Dev->Set(String::New("addresses"), AddrArray); Dev->Set(String::New("addresses"), AddrArray);
Expand Down

0 comments on commit f0c04a5

Please sign in to comment.