210 likes | 323 Views
Chapter 17 routing sockets. abstract. Introduction datalink socket address structure reading and writing sysctl operation get_ifi_info function interface name and index fuction. Introduction. Access the Unix routing table within the kernel ioctl command (SIOCADDRT, SIODELRT)
E N D
abstract • Introduction • datalink socket address structure • reading and writing • sysctl operation • get_ifi_info function • interface name and index fuction
Introduction • Access the Unix routing table within the kernel • ioctl command (SIOCADDRT, SIODELRT) • netstat: read the kernel memory to obtain the contents of the routing table • Routing daemons (gated) • monitor ICMP • AF_ROUTE domain => cleaned up the interface to the kernel’s routing system • only type of socket supported in the route domain => raw socket
Three type of operation on routing socket • process can send a message to the kernel by writing to a routing socket(addition and deletion of routes, Only superuser) • process can read a message from the kernel on a routing socket (Only superuser) • process can use the sysctl function to either dump the routing table or to list all the configured interface
datalink socket address structure • Returned by routing socket <net/if_dl.h> Structure 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*/ };
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 • Three different structure are exchanged across a routing socket • rt_msghdr, if_msghdr, ifa_msghdr (figure 17-3)
Data exchanged with kernel across routing socket for RTM_GET command
Figure 17-6 #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;
Figure 17-6(2) 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);
Figure 17-6(2) 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); }
Figure 17-9 #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; } }
sysctl operation • Any process can examine both the routing table and the interface list. #include <sys/param.h> #include <sys/sysctl.h> int sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); returns:0 if OK, -1 on error
Information returned for sysctl,CTL_NET,NET_RT_IFLIST command One per interface: interface name, index, and hardware address One per address: configured for the interface
Figure 17-14 #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); printf("udp checksum flag: %d\n", val); exit(0); }
interface name and index fuction • RFC 2133 defines four function that deal with interface names and indexes ==>these are used with IPv6 multicasting(chapter 19) • each interface has a unique name and a unique positive index(0 is never used )
#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);
if_nameindex return a pointer to an array of if_nameindex structure Struct if_nameindex{ unsigned int if_index;/*1, 2,…...*/ char *if_name;/*null terminated name*/ }