Ejemplo n.º 1
0
int
kernel_routes(struct kernel_route *routes, int maxroutes)
{
    int mib[6];
    char *buf, *p;
    size_t len;
    struct rt_msghdr *rtm;
    int rc, i;
    
    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_UNSPEC;      /* Address family */
    mib[4] = NET_RT_DUMP; /* Dump the kernel routing table */
    mib[5] = 0;		  /* No flags */

    rc = sysctl(mib, 6, NULL, &len, NULL, 0);
    if (rc < 0) {
        perror("kernel_routes(len)");
        return -1;
    }

    buf = malloc(len);
    if(!buf) {
        perror("kernel_routes(malloc)");
        return -1;
    }

    rc = sysctl(mib, 6, buf, &len, NULL, 0);
    if (rc < 0) {
        perror("kernel_routes(dump)");
        goto fail;
    }

    i = 0;
    p = buf;
    while(p < buf + len && i < maxroutes) {
        rtm = (struct rt_msghdr*)p;
        rc = parse_kernel_route(rtm, &routes[i]);
        if(rc)
            goto cont;

        if(debug > 2)
            print_kernel_route(1,&routes[i]);

        i++;

    cont:
        p += rtm->rtm_msglen;
    }

    free(buf);
    return i;

 fail:
    free(buf);
    return -1;

}
Ejemplo n.º 2
0
static int
socket_read(int sock) 
{
    int rc;
    struct {
        struct rt_msghdr rtm;
        struct sockaddr_storage addr[RTAX_MAX];
    } buf;

    rc = read(sock, &buf, sizeof(buf));
    if(rc <= 0) {
        perror("kernel_callback(read)");
        return 0;
    }

    if(buf.rtm.rtm_msglen != rc) {
        kdebugf("kernel_callback(length)\n");
        return -1;
    }

    if(buf.rtm.rtm_type == RTM_ADD ||
       buf.rtm.rtm_type == RTM_DELETE || 
       buf.rtm.rtm_type == RTM_CHANGE) {
        struct kernel_route route;

        if(buf.rtm.rtm_errno)
            return 0;

        rc = parse_kernel_route(&buf.rtm, &route);
        if(rc < 0)
            return 0;
        if(debug > 2)
            print_kernel_route(1,&route);
        return 1;

    }

    return 0;

}
Ejemplo n.º 3
0
static int
filter_kernel_routes(struct nlmsghdr *nh, void *data)
{
    int rc;

    struct kernel_route *current_route;
    struct kernel_route route;

    int maxroutes = 0;
    struct kernel_route *routes = NULL;
    int *found = NULL;
    int len;

    struct rtmsg *rtm;

    if(data) {
        void **args = (void**)data;
        maxroutes = *(int*)args[0];
        routes = (struct kernel_route *)args[1];
        found = (int*)args[2];
    }

    len = nh->nlmsg_len;

    if(data && *found >= maxroutes)
        return 0;

    if(nh->nlmsg_type != RTM_NEWROUTE &&
       (data || nh->nlmsg_type != RTM_DELROUTE))
        return 0;

    rtm = (struct rtmsg*)NLMSG_DATA(nh);
    len -= NLMSG_LENGTH(0);

    if(rtm->rtm_protocol == RTPROT_BABEL)
        return 0;

    if(rtm->rtm_src_len != 0)
        return 0;

    if(data)
        current_route = &routes[*found];
    else
        current_route = &route;

    rc = parse_kernel_route_rta(rtm, len, current_route);
    if(rc < 0)
        return 0;

    if(martian_prefix(current_route->prefix, current_route->plen))
        return 0;

    /* Ignore default unreachable routes; no idea where they come from. */
    if(current_route->plen == 0 && current_route->metric >= KERNEL_INFINITY)
        return 0;

    if(debug >= 2) {
        if(rc >= 0) {
            print_kernel_route(nh->nlmsg_type, rtm->rtm_protocol,
                               rtm->rtm_type, current_route);
        }
    }

    if (data) *found = (*found)+1;

    return 1;

}