Program I use:
include <stdio.h>
#include <pcap/pcap.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(void)
{
int ret;
struct in_addr net;
struct in_addr mask;
char error_message[PCAP_ERRBUF_SIZE];
ret = pcap_lookupnet("en1", (bpf_u_int32*)&net.s_addr, (bpf_u_int32*)&mask.s_addr, error_message);
if(ret == -1)
{
printf("[!] Error: %s\n", error_message);
return 1;
}
printf("[+] Network number: %s\n[+] Subnet mask: %s\n", inet_ntoa(net), inet_ntoa(mask));
return 0;
}
Real output:
[+] Network number: 172.24.8.0
[+] Subnet mask: 172.24.8.0
Expected output:
[+] Network number: 172.24.8.0
[+] Subnet mask: 255.255.248.0
ifconfig output:
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether d8:a2:5e:94:85:f2
inet6 fe80::daa2:5eff:fe94:85f2%en1 prefixlen 64 scopeid 0x5
inet 172.24.8.13 netmask 0xfffff800 broadcast 172.24.15.255
media: autoselect
status: active
This program, however:
#include <stdio.h>
#include <pcap/pcap.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(void)
{
int ret;
struct in_addr net;
struct in_addr mask;
char error_message[PCAP_ERRBUF_SIZE];
ret = pcap_lookupnet("en1", (bpf_u_int32*)&net.s_addr, (bpf_u_int32*)&mask.s_addr, error_message);
if(ret == -1)
{
printf("[!] Error: %s\n", error_message);
return 1;
}
printf("[+] Network number: %08x\n[+] Subnet mask: %08x\n", net.s_addr, mask.s_addr);
return 0;
}
prints
[+] Network number: 0001000a
[+] Subnet mask: 00ffffff
on my machine:
$ ifconfig en1
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether XX:XX:XX:XX:XX:XX
inet6 XXXX::XXXX:XXXX:XXXX:XXXX%en1 prefixlen 64 scopeid 0x6
inet 10.0.1.4 netmask 0xffffff00 broadcast 10.0.1.255
To quote the BUGS section of the man page for inet_ntoa on my machine:
The string returned by inet_ntoa() resides in a static memory area.
That means that if you use it to generate two arguments to a printf-style format in a single call to a printf-style routine, the call that's done later will overwrite the result of the call that's done earlier, so it'll print the same string twice.
Use inet_ntop() instead - it formats the address into a specified buffer, so you can specify two buffers; this program:
#include <stdio.h>
#include <pcap/pcap.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(void)
{
int ret;
struct in_addr net;
char netbuf[3+1+3+1+3+1+3+1];
struct in_addr mask;
char maskbuf[3+1+3+1+3+1+3+1];
char error_message[PCAP_ERRBUF_SIZE];
ret = pcap_lookupnet("en1", (bpf_u_int32*)&net.s_addr, (bpf_u_int32*)&mask.s_addr, error_message);
if(ret == -1)
{
printf("[!] Error: %s\n", error_message);
return 1;
}
printf("[+] Network number: %s\n[+] Subnet mask: %s\n",
inet_ntop(AF_INET, &net, netbuf, sizeof netbuf),
inet_ntop(AF_INET, &mask, maskbuf, sizeof maskbuf));
return 0;
}
prints
[+] Network number: 10.0.1.0
[+] Subnet mask: 255.255.255.0
Administrators of the "libpcap" SourceForge project have superseded this tracker item (formerly artifact 3491131, now bug 158) with issue 160 of the "libpcap" GitHub project.