I wrote this for testing/debug purpose.
/* $Id$ */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <fcntl.h> #include <unistd.h> #include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/sysctl.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/route.h> #include <net/if.h> #include <net/if_dl.h> #include <strings.h> #include <arpa/inet.h> int main(void) { char *c_dstip = "10.2.3.0"; char *c_maskip = "255.255.255.0"; char *c_gwip = "192.168.56.1"; u_long dstip, gwip, maskip; u_short flags; int s, rc; struct { struct rt_msghdr hdr; struct sockaddr_in dst; struct sockaddr_in gateway; struct sockaddr_in mask; } rtmsg; s = socket(PF_ROUTE, SOCK_RAW, 0); if (s < 0) { printf("error: socket\n"); return -1; } shutdown(s, SHUT_RD); flags |= (RTF_UP | RTF_GATEWAY); bzero(&rtmsg, sizeof(rtmsg)); rtmsg.hdr.rtm_type = RTM_ADD; rtmsg.hdr.rtm_version = RTM_VERSION; rtmsg.hdr.rtm_addrs = 0; rtmsg.hdr.rtm_addrs |= RTA_DST; rtmsg.hdr.rtm_addrs |= RTA_GATEWAY; rtmsg.hdr.rtm_addrs |= RTA_NETMASK ; rtmsg.hdr.rtm_flags = 0; rtmsg.hdr.rtm_flags |= RTF_GATEWAY; // rtmsg.hdr.rtm_flags |= RTF_HOST; rtmsg.hdr.rtm_flags |= RTF_GATEWAY; rtmsg.hdr.rtm_addrs |= RTA_GATEWAY; // ----- dstip ----- int r = inet_pton(AF_INET, c_dstip, &dstip); rtmsg.dst.sin_len = sizeof(rtmsg.dst); rtmsg.dst.sin_family = AF_INET; rtmsg.dst.sin_addr.s_addr = dstip; // ------ mask ----- r = inet_pton(AF_INET, c_maskip, &maskip); rtmsg.mask.sin_len = sizeof(rtmsg.mask); rtmsg.mask.sin_family = AF_INET; rtmsg.mask.sin_addr.s_addr = maskip; // ------ gwip ----- r = inet_pton(AF_INET, c_gwip, &gwip); rtmsg.gateway.sin_len = sizeof(rtmsg.gateway); rtmsg.gateway.sin_family = AF_INET; rtmsg.gateway.sin_addr.s_addr = gwip; rc = sizeof(rtmsg); rtmsg.hdr.rtm_msglen = rc + 4; if ((rc = write(s, &rtmsg, rc)) < 0) { printf("error: writing to routing socket\n"); return -1; } return (rc); } /* EOF */