You are on page 1of 28

Schedule

• Term Project (Submission):


– Saturday June 17, 2006 (All students will present)
5:00 PM-8:30 PM

• Term Paper Report:


– Monday June 19, 2006

• Term Paper Presentation:


– Wednesday June 28, 2006 6:00 PM - 7:30 PM
– Friday June 30, 2006 5:00 PM – 8:00 PM
Routing Sockets

A Ghafoor
Contents
• Introduction
• Routing table
• Operation on routing sockets
• Datalink socket address structure
• Structures for routing sockets
• Reading and writing
• sysctl operation
• Interface name and index function
Introduction
• Access the Unix routing table within the kernel
– ioctl command (SIOCADDRT, SIODELRT) is used to
add and delete an entry to/from routing table but entire
routing table can’t be accessed
– netstat: read the kernel memory to obtain the contents
of the routing table
• Routing daemons (gated)
– Need to monitor ICMP redirect messages that are
received by the kernel (RAW_SOCK)
– The raw sockets created with AF_ROUTE domain
sockets can cleaned up the interface to the kernel’s
routing system
Routing table
Operation on routing socket
S – A process can send a message to the kernel by
U
P writing to a routing socket(addition and
E deletion of routes)
R
U – A process can read a message from the kernel
S on a routing socket. In this way a process can
E
R perform route resolution and receives ICMP
notifications.
P
R
O
– A process can use the sysctl function to either
C
E
dump the routing table or to list all the
S
S
configured interface
Datalink socket address structure
• Returned by routing socket <net/if_dl.h>

struct sockaddr_dl
{
uint8_t sdl_len;
sa_family_t sdl_family; /*AF_LINK*/
uint16_t sdl_index; /*system assigned index*/
uint8_t sdl_type; /*IFT_ETHER*/
uint8_t sdl_nlen; /*name length*/
uint8_t sdl_alen; /*link-layer address length*/
uint8_t sdl_slen; /* link-layer selector length */
char sdl_data[12]; /*minimum work area, name
and link-layer address*/
};
Datalink socket address structure

• Each interface has unique positive index


– Returned by if_nametoindex or if_nameindex functions
• sdl_data member contains name and address
– 48 bit MAC address
– The name begins at sdl_data[0] and link layer address
begins sdl_nlen bytes after the name
– #define LLADDR (s) ((caddr_t) ((s)->sdl_data+(s)->sdl
_nlen)) macro return the pointer to the LL addresses.
• Length of sockaddr_dl may vary.
Structures for routing sockets
• Five different structures are exchanged across a routi
ng socket
– rt_msghdr, if_announce_msg_hdr, if_msg_hdr, ifa_msg_h
dr, ifma_msghdr

• The first three members of each structure is same: len


gth, version and type
– Type is one of the constants from commands
• The members rtm_addrs, ifm_addrs, ifam_addrs and
ifmam_addrs are bit masks
– These specify which of eight possible socket address struct
ure follow the message.
– These constant are defined in the <net/route.h>
Commands
Bitmasks
Bitmask Array Index Socket address structure
Constant Value Constant Value containing

RTA_DST 0x01 RTAX_DST 0 Destination address


RTA_GATEWAY 0x02 RTAX_GATEWAY 1 Gateway address

RTA_NETMASK 0x04 RTAX_NETMASK 2 Network mask

RTA_GENMASK 0x08 RTAX_GENMASK 3 Cloning mask

RTA_IFP 0x10 RTAX_IFP 4 Interface name


RTA_IFA 0x20 RTAX_IFA 5 Interface address
RTA_AUTHOR 0x40 RTAX_AUTHOR 6 Author of redirect
Broadcast or point-point
RTA_BRD 0x80 RTAX_BRD 7 destination address
RTAX_MAX 8 Max # elements
Reading and Writing
• After a process create a routing socket, it
can send commands to the kernel by writing
to the socket and read information from the
kernel by reading from the socket
• There are 12 different routing commands
that identifies message type
• These are defined in <net/route.h>
Data exchanged with kernel across routing socket
for RTM_GET command
buffer sent buffer returned
to kernel by kernel

rt_msghdr{} rt_msghdr{}

rtm_type = rtm_type =
RTM_GET RTM_GET

destination destination
socket socket RTA_DST
address address
structure
structure
RTA_DST gateway
socket RTA_GAT
address EWAY
structure
netmask
socket RTA_NET
address MASK
structure
genmask
socket RTA_GE
address NMASK
structure
Reading routing table (RTM_GET)

#include "unproute.h"
#define BUFLEN (sizeof(struct rt_msghdr) + 512)
/* 8 * sizeof(struct sockaddr_in6) = 192 */
#define SEQ 9999
int main(int argc, char **argv)
{
int sockfd;
char *buf;
pid_t pid;
ssize_t n;
struct rt_msghdr *rtm;
struct sockaddr *sa, *rti_info[RTAX_MAX];
struct sockaddr_in *sin;
if (argc != 2) err_quit("usage: getrt <IPaddress>");
sockfd = socket(AF_ROUTE, SOCK_RAW, 0); /* need superuser privileges */
buf = calloc(1, BUFLEN); /* and initialized to 0 */
rtm = (struct rt_msghdr *) buf;
rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
rtm->rtm_version = RTM_VERSION;
rtm->rtm_type = RTM_GET;
rtm->rtm_addrs = RTA_DST;
rtm->rtm_pid = pid = getpid();
rtm->rtm_seq = SEQ;

sin = (struct sockaddr_in *) (rtm + 1);


sin->sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &sin->sin_addr);

write(sockfd, rtm, rtm->rtm_msglen);


do {
n = read(sockfd, rtm, BUFLEN);
} while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ ||
rtm->rtm_pid != pid);
rtm = (struct rt_msghdr *) buf;
sa = (struct sockaddr *) (rtm + 1);
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
if ( (sa = rti_info[RTAX_DST]) != NULL)
printf("dest: %s\n", sock_ntop_host(sa, sa->sa_len));

if ( (sa = rti_info[RTAX_GATEWAY]) != NULL)


printf("gateway: %s\n", sock_ntop_host(sa, sa->sa_len));

if ( (sa = rti_info[RTAX_NETMASK]) != NULL)


printf("netmask: %s\n", sock_masktop(sa, sa->sa_len));

if ( (sa = rti_info[RTAX_GENMASK]) != NULL)


printf("genmask: %s\n", sock_masktop(sa, sa->sa_len));
exit(0);
}
get_rtaddrs user defined functions
#include "unproute.h"
#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
/* Step to next socket address structure;
if sa_len is 0, assume it is sizeof(u_long).
*/
#define NEXT_SA(ap) ap = (struct sockaddr *) \
((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (u_long)) : \
sizeof(u_long)))

void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)


{
int i;
for (i = 0; i < RTAX_MAX; i++) {
if (addrs & (1 << i)) {
rti_info[i] = sa;
NEXT_SA(sa);
} else rti_info[i] = NULL;
}
}
rti_info structure filled in by our get_rtaddrs function
buffer returned
by kernel

rt_msghdr{}

rtm_type =
RTM_GET

rti_info[RTAX_DST] destination
socket RTA_DST
rti_info[RTAX_GATEWAY] address
rti_info[RTAX_NETMASK] structure
gateway
rti_info[RTAX_GENMASK] socket RTA_GAT
address EWAY
rti_info[RTAX_IFP] NULL
structure
rti_info[RTAX_IFA] NULL netmask
socket RTA_NET
rti_info[RTAX_AUTHOR] NULL
address MASK
rti_info[RTAX_BRD] NULL structure
genmask
socket RTA_GE
address NMASK
structure
sysctl operation

• Any<sys/param.h>
#include process can examine both the routing table
and<sys/sysctl.h>
#include the interface list.
• Any user can view the routing table and
interface
int sysctl(int list. u_int namelen, void *oldp, size_t
*name,
*oldlenp, void *newp, size_t newlen);

returns:0 if OK, -1 on error

name: Specify the name like SNMP MIB (tree type)


namelen: number of element in the array
oldp: points the buffer into which the kernel stores the value
newp: to set a new value
Hierarchical arrangement of sysctl names
CTL_DEBUG CTL_HW CTL_KERN CTL_NET CTL_USER CTL_VFS

AF_INET AF_LINE AF_ROUTE AF_UNSPEC

IPPROTO_ICMP IPPROTO_IGMP IPPROTO_IP IPPROTO_TCP IPPROTO_UDP

Sysctl can return various system information but we are interested in


network related information
sysctl operation

• name array: If first element of name array is


CTL_NET then second may be

– AF_INET: next level specifies the protocol using one of the


IPPROTO_xxx.

– AF_LINK: to get link layer information.

– AF_UNSPEC: to get or set socket layer variables

AF ROUTE: returns information on routing table of interfa


Sysctl information returned for route
domain

name[] return IPv4 return IPv4 return


routing table arp cache interface list

0 CTL_NET
CTL_NET CTL_NET
1 AF_ROUTE
AF_ROUTE AF_ROUTE
2 0
0 0
3 AF_INET
AF_INET AF_INET

4 NET_RT_DUMP NET_RT_FLAGS NET_RT_IFLIST

5 0 RTF_LLINFO 0
Three operations are supported by
name[4]
• NET_RT_DUMP:
– returns the routing table for the address family specified in n
ame[3]
– If address family is 0, routing table for all address families a
re returned
– Return: destination, gateway, network mask, and cloning m
ask

• NET_RT_FLAGS:
– Only the routing table with RTF_xxx flag values that contai
n the flags specified by name[5]
– All ARP cache entries in routing table have the RTF_FLAG
bit set
Information returned for sysctl,CTL_NET,NET_RT_IFLIST
command buffer returned
by kernel

if_msghdr{} One per interface:


ifm_type = interface name,
RTM_IFINFO
index, and
datalink
hardware address
socket
address
structure
ifa_msghdr{}
ifam_type =
RTM_NEWADDR

netmask
socket
address
One per address:
structure
unicast addr configured for the
socket interface
address
structure
broadcast addr
socket
address
structure
UDP Checksum
#include "unproute.h"
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h> /* for
UDPCTL_xxx constants */

int main(int argc, char **argv)


{
int mib[5], val;
size_t len;
mib[0] = CTL_NET;
mib[1] = AF_INET;
mib[2] = IPPROTO_UDP;
mib[3] = UDPCTL_CHECKSUM;
len = sizeof(val);
sysctl(mib, 4, &val, &len, NULL, 0);
Interface name and index
function

• RFC 2133 defines four function that deal


with interface names and indexes
– these are used with IPv6
– Multicasting

• Each interface has a unique name and a


unique positive index (0 is never used )
Index name functions

#include <net/if.h>
unsigned int if_nametoindex(const char *ifname);
returns:positive interface index if OK, 0 on error
char *if_indextoname(unsigned int ifindex, char *ifname);
returns:pointer to interface name if OK, NULL on error
struct if_nameindex *if_nameindex(void);
returns:nonnull pointer if OK, NULL on error
void if_freenameindex(struct if_nameindex *ptr);

Struct if_nameindex {
unsigned int if_index;/*1, 2,…...*/
char *if_name;/*null terminated name*/
}
Home Assignment

Display complete routing table using RAW


sockets

You might also like