// Title: display_ip_address.c
// Purpose: Display IP, Netmask, Broadcast, and MAC
//--------------------------------------------------------
// REFERENCES:
// http://www.beej.us/guide/bgnet/output/html/multipage/structs.html
// http://www.basepath.com/aup/ex/structsockaddr__in.html
// http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=getifaddrs
// http://www.hmug.org/man/3/getifaddrs.php
//--------------------------------------------------------
#include <stdio.h> /* standard io headers */
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h> /* defines sturct addr_sockaddr_in */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h> /* getifaddrs() */
#include <netinet/ether.h> /* ether_ntoa() */
#include <netpacket/packet.h> /* struct sockaddr_ll */
#define MY_INTERFACE "ath0"
#define DEBUG 1
//--------------------------------------------------------//
int main()
{
struct ifaddrs *id; // linked list of structs (id->ifa_next points to next element)
struct sockaddr_in *addr_sockaddr_in; // sockaddr_in has an in_addr member
struct sockaddr_in *netmask_sockaddr_in; // sockaddr_in has an ifa_netmask member
struct ether_addr *mac_ether_addr; // ether_addr, cast to
struct sockaddr_ll *mac_sockaddr_ll; //
struct sockaddr_ll *ip_sockaddr_ll = (struct sockaddr_ll *)(id->ifa_addr);
char *ascii_ip_address; // holds 'dots-and-number' ip address
char *ascii_netmask_address; // holds 'dots-and-number' netmask address
char *ascii_broadcast_address; // holds 'dots-and-number' broadcast address
char *ascii_mac_address; // hods the 'colon-and-numbers' mac address
char *ascii_interface; // holds name of the network interface
int val; // socket descriptor is junst an int
val = getifaddrs(&id); // getifaddrs function stores a reference to a linked list of the network interfaces
//
for ( ; id != NULL ; id = id->ifa_next) // Loop through all interfaces known to getifaddrs
// enter section below,
// then point to next struct in linked list
{
if ( id->ifa_addr != NULL ) // ifa_addr contains either interface address OR link level address OR NULL
{
if ( id->ifa_addr->sa_family == AF_INET ) // "AF_INET" means internetwork: UDP, TCP, etc. */
{
if ( strcmp(id->ifa_name, MY_INTERFACE) == 0 ) // if 'id->ifa_name' is MY_INTERFACE,enter section
{
ascii_interface=id->ifa_name; // Output interface name string
if( DEBUG )
{
printf("Interface: %s\n", ascii_interface); // Output the 'dots-and-number' ip
}
//--------------------------------------------------------//
// IP
//
//--------------------------------------------------------//
addr_sockaddr_in = (struct sockaddr_in *)(id->ifa_addr); // cast struct sockaddr to struct sockaddr_in,
// sockaddr_in has an ifa_addr member, but sockaddr doesn't
ascii_ip_address = inet_ntoa( addr_sockaddr_in->sin_addr ); // convert socket ip to 'dots-and-number' ip
if( DEBUG )
{
printf("IP Address: %s\n", ascii_ip_address); // Output the 'dots-and-number' ip
}
//--------------------------------------------------------//
// Netmask
//--------------------------------------------------------//
if ( id->ifa_netmask != NULL ) // checking for null before processing.
{
netmask_sockaddr_in = (struct sockaddr_in *)(id->ifa_netmask); // cast struct sockaddr to be struct sockaddr_in,
// sockaddr_in has an ifa_netmask member, but sockaddr doesn't
ascii_netmask_address = inet_ntoa( netmask_sockaddr_in->sin_addr ); // convert socket ip to 'dots-and-number' ip
if( DEBUG )
{
printf("Netmask: %s\n", ascii_netmask_address); // Output the 'dots-and-number' netmask
}
}
//--------------------------------------------------------//
// Broadcast
//--------------------------------------------------------//
if ( id->ifa_broadaddr != NULL ) // checking for null before processing.
{
netmask_sockaddr_in = (struct sockaddr_in *)(id->ifa_broadaddr); // cat struct sockaddr to be sturct sockaddr_in,
ascii_broadcast_address = inet_ntoa( netmask_sockaddr_in->sin_addr ); // struct sockaddr_in has an ifa_broadaddr member,
// but sockaddr doesn't
if( DEBUG )
{
printf("Broadcast: %s\n", ascii_broadcast_address); // Output the 'dots-and-number' broadcast
}
}
}
}
}
//--------------------------------------------------------//
// MAC
//--------------------------------------------------------//
if ( id->ifa_addr->sa_family == AF_PACKET ) // "AF_PACKET" contains the mac
{
//if ( strcmp(id->ifa_name, "lo") != 0 ) // if 'id->ifa_name' is not loopback (lo),enter section
if ( strcmp(id->ifa_name, MY_INTERFACE ) == 0 ) // if 'id->ifa_name' is MY_INTERFACE,enter section
{
mac_sockaddr_ll = (struct sockaddr_ll *)(id->ifa_addr); // cast struct sockaddr to be struct sockaddr_ll
// sockaddr_ll has member sll_addr (the mac)
if ( mac_sockaddr_ll->sll_hatype == ARPHRD_ETHER) // check for correct hatype to have a mac
{
ascii_mac_address = ether_ntoa((struct ether_addr *)(mac_sockaddr_ll->sll_addr)); // cast sturct sockaddr_ll to struct ether_addr
// ether_ntoa only works on struct ether_addr
if( DEBUG )
{
printf("MAC: %s\n", ascii_mac_address); // Output the 'dots-and-number' mac
}
}
}
//break; // Just grab first interface
//printf("\n"); // Print all interfaces
}
}
// should run freeifaddrs();
freeifaddrs (id);
printf("%s %s %s %s %s\n", ascii_interface, ascii_ip_address, ascii_netmask_address, ascii_broadcast_address, ascii_mac_address);
return 0;
}