Ejemplo n.º 1
0
void DoSetIpForwardEntry(char* pszDest, char* pszNetMask, char* pszGateway, char* pszInterface, DWORD dwMetric)
{
    DWORD dwStatus;

    MIB_IPFORWARDROW routeEntry;            // Ip routing table row entry
    PMIB_IPADDRTABLE pIpAddrTable = NULL;   // Ip Addr Table
    DWORD dwIfIndex;                        // Interface index number  
    DWORD dwIfMask;                         // Interface Subnet Mask
    DWORD dwIfIpAddr;                       // Interface Ip Address
    
    memset(&routeEntry, 0, sizeof(MIB_IPFORWARDROW));
    

    // converting and checking input arguments...
    if (pszDest == NULL || pszNetMask == NULL || pszGateway == NULL)
    {
        printf("IpRoute: Bad Argument\n");
        return;
    }

    routeEntry.dwForwardDest = inet_addr(pszDest); // convert dotted ip addr. to ip addr.
    if (routeEntry.dwForwardDest == INADDR_NONE)
    {
        printf("IpRoute: Bad Destination %s\n", pszDest);
        return;
    }

    routeEntry.dwForwardMask = inet_addr(pszNetMask);
    if ( (routeEntry.dwForwardMask == INADDR_NONE) && 
         (strcmp("255.255.255.255", pszNetMask) != 0) )
    {
        printf("IpRoute: Bad Mask %s\n", pszNetMask);
        return;
    }

    routeEntry.dwForwardNextHop = inet_addr(pszGateway);
    if (routeEntry.dwForwardNextHop == INADDR_NONE)
    {
        printf("IpRoute: Bad Gateway %s\n", pszGateway);
        return;
    }

    if ( (routeEntry.dwForwardDest & routeEntry.dwForwardMask) != routeEntry.dwForwardDest)
    {
        printf("IpRoute: Invalid Mask %s\n", pszNetMask);
        return;
        
    }

    dwIfIpAddr = inet_addr(pszInterface);
    if (dwIfIpAddr == INADDR_NONE)
    {
        printf("IpRoute: Bad Interface %s\n", pszInterface);
        return;
    }


    // Check if we have the given interface
    if ( (dwStatus = MyGetIpAddrTable(pIpAddrTable)) != NO_ERROR)
    {
        printf("GetIpAddrTable returned 0x%x\n", dwStatus);
        if (pIpAddrTable)
            free(pIpAddrTable);
        return;
    }
    assert(pIpAddrTable);
    if ( InterfaceIpToIdxAndMask(pIpAddrTable, pszInterface, dwIfIndex, dwIfMask) == FALSE)
    {
        printf("IpRoute: Bad Argument %s\n", pszInterface);
        return;
    }
    free(pIpAddrTable);


    if ( (routeEntry.dwForwardNextHop & dwIfMask) != (dwIfIpAddr & dwIfMask) )
    {
        printf("IpRoute: Gateway %s and Interface %s are not in the same subnet.\n", pszGateway, pszInterface);
        return;
    }

    routeEntry.dwForwardIfIndex = dwIfIndex;
    
    routeEntry.dwForwardMetric1 = dwMetric;

    // some default values
    routeEntry.dwForwardProto = MIB_IPPROTO_NETMGMT;
    routeEntry.dwForwardMetric2 = (DWORD)-1;
    routeEntry.dwForwardMetric3 = (DWORD)-1;
    routeEntry.dwForwardMetric4 = (DWORD)-1;
    
    dwStatus = SetIpForwardEntry(&routeEntry); 
    if (dwStatus != NO_ERROR)
    {
        printf("IpRoute: couldn't add (%s), dwStatus = %lu.\n",
                    pszDest, dwStatus);
    }

}
Ejemplo n.º 2
0
int
write_rte(int action,
          u_char * var_val,
          u_char var_val_type,
          size_t var_val_len, u_char * statP, oid * name, size_t length)
{
    int             var, retval = NO_ERROR;
    static PMIB_IPFORWARDROW oldroute_row = NULL;
    static int      mask_flag = 0, nexthop_flag = 0;
    static int      index_flag = 0, metric_flag = 0;
    static int      dest_flag = 0;
    DWORD           status = NO_ERROR;
    /*
     * object identifier is of form:
     * 1.3.6.1.2.1.4.21.1.X.A.B.C.D ,  where A.B.C.D is IP address.
     * IPADDR starts at offset 10.
     */

    if (length != 14) {
        snmp_log(LOG_ERR, "length error\n");
        return SNMP_ERR_NOCREATION;
    }
    /*
     * #define for ipRouteTable entries are 1 less than corresponding sub-id in MIB
     * * i.e. IPROUTEDEST defined as 0, but ipRouteDest registered as 1
     */
    var = name[9] - 1;

    switch (action) {
    case RESERVE1:
        switch (var) {
        case IPROUTEMETRIC1:
        case IPROUTEMETRIC2:
        case IPROUTEMETRIC3:
        case IPROUTEMETRIC4:
        case IPROUTEMETRIC5:
        case IPROUTETYPE:
        case IPROUTEAGE:
        case IPROUTEIFINDEX:
            if (var_val_type != ASN_INTEGER) {
                snmp_log(LOG_ERR, "not integer\n");
                return SNMP_ERR_WRONGTYPE;
            }
            if (var_val_len > sizeof(int)) {
                snmp_log(LOG_ERR, "bad length\n");
                return SNMP_ERR_WRONGLENGTH;
            }
            if (var == IPROUTETYPE) {
                if ((*((int *) var_val)) < 2 || (*((int *) var_val)) > 4) {
                    snmp_log(LOG_ERR, "invalid ipRouteType\n");
                    return SNMP_ERR_WRONGVALUE;
                }
            } else if ((var == IPROUTEIFINDEX) || (var == IPROUTEAGE)) {
                if ((*((int *) var_val)) < 0) {
                    snmp_log(LOG_ERR, "invalid ipRouteIfIndex\n");
                    return SNMP_ERR_WRONGVALUE;
                }
            } else {
                if ((*((int *) var_val)) < -1) {
                    snmp_log(LOG_ERR, "not right1");
                    return SNMP_ERR_WRONGVALUE;
                }
            }
            break;
        case IPROUTENEXTHOP:
        case IPROUTEMASK:
        case IPROUTEDEST:
            if (var_val_type != ASN_IPADDRESS) {
                snmp_log(LOG_ERR, "not right4");
                return SNMP_ERR_WRONGTYPE;
            }
            if (var_val_len != 4) {
                snmp_log(LOG_ERR, "incorrect ipAddress length");
                return SNMP_ERR_WRONGLENGTH;
            }
            break;
        default:
            DEBUGMSGTL(("snmpd", "unknown sub-id %d in write_rte\n",
                        var + 1));
            retval = SNMP_ERR_NOTWRITABLE;
        }
        break;

    case RESERVE2:
        /*
         * Save the old value, in case of UNDO 
         */
        if (oldroute_row == NULL) {
            oldroute_row =
                (PMIB_IPFORWARDROW) malloc(sizeof(MIB_IPFORWARDROW));
            *oldroute_row = *route_row;
        }
        break;

    case ACTION:               /* Perform the SET action (if reversible) */
        switch (var) {
        case IPROUTEMETRIC1:
            metric_flag = 1;
            route_row->dwForwardMetric1 = *((int *) var_val);
            break;
        case IPROUTEMETRIC2:
            route_row->dwForwardMetric2 = *((int *) var_val);
            break;
        case IPROUTEMETRIC3:
            route_row->dwForwardMetric3 = *((int *) var_val);
            break;
        case IPROUTEMETRIC4:
            route_row->dwForwardMetric4 = *((int *) var_val);
            break;
        case IPROUTEMETRIC5:
            route_row->dwForwardMetric5 = *((int *) var_val);
            break;
        case IPROUTETYPE:
            route_row->dwForwardType = *((int *) var_val);
            break;
        case IPROUTEAGE:
            /*
             * Irrespective of suppied value, this will be set with 0.
             * * As row will be updated and this field gives the number of 
             * * seconds since this route was last updated
             */
            route_row->dwForwardAge = *((int *) var_val);
            break;
        case IPROUTEIFINDEX:
            index_flag = 1;
            route_row->dwForwardIfIndex = *((int *) var_val);
            break;

        case IPROUTENEXTHOP:
            nexthop_flag = 1;
            route_row->dwForwardNextHop = *((DWORD *) var_val);
            break;
        case IPROUTEMASK:
            mask_flag = 1;
            route_row->dwForwardMask = *((DWORD *) var_val);
            break;
        case IPROUTEDEST:
            dest_flag = 1;
            route_row->dwForwardDest = *((DWORD *) var_val);
            break;
        default:
            DEBUGMSGTL(("snmpd", "unknown sub-id %d in write_rte\n",
                        var + 1));
            retval = SNMP_ERR_NOTWRITABLE;
        }
        return retval;
    case UNDO:
        /*
         * Reverse the SET action and free resources 
         */
        if (oldroute_row) {
            *route_row = *oldroute_row;
            free(oldroute_row);
            oldroute_row = NULL;
            free(route_row);
            route_row = NULL;
        }
        break;

    case COMMIT:
        /*
         * When this case entered 'route_row' will have user supplied values for asked entries. 
         * * Thats why it is enough if we call SetIpForwardEntry/CreateIpForwardEntry only once 
         * * SetIpForwardENtry is not done in ACTION phase, as that will reset ipRouteAge on success
         * * and if any varbind fails, then we can't UNDO the change for ipROuteAge. 
         */
        if (route_row) {
            if (!create_flag) {

                if (SetIpForwardEntry(route_row) != NO_ERROR) {
                    snmp_log(LOG_ERR,
                             "Can't set route table's row with specified value\n");
                    retval = SNMP_ERR_COMMITFAILED;
                } else {
                    /*
                     * SET on IpRouteNextHop, IpRouteMask & ipRouteDest creates new row. 
                     * *If Set succeeds, then delete the old row.
                     * * Don't know yet whether SET on ipRouteIfIndex creates new row.
                     * * If it creates then index_flag should be added to following if statement
                     */

                    if (dest_flag || nexthop_flag || mask_flag) {
                        oldroute_row->dwForwardType = 2;
                        if (SetIpForwardEntry(oldroute_row) != NO_ERROR) {
                            snmp_log(LOG_ERR,
                                     "Set on ipRouteTable created new row, but failed to delete the old row\n");
                            retval = SNMP_ERR_GENERR;
                        }
                    }
                }
            }
            /*
             * Only if create_flag, mask, nexthop, ifIndex and metric are specified, create new entry 
             */
            if (create_flag) {
                if (mask_flag && nexthop_flag && metric_flag && index_flag) {
                    if ((status =
                         CreateIpForwardEntry(route_row)) != NO_ERROR) {
                        snmp_log(LOG_ERR,
                                 "Inside COMMIT: CreateIpNetEntry failed, status %lu\n",
                                 status);
                        retval = SNMP_ERR_COMMITFAILED;
                    }
                } else {
                    /*
                     * For new entry, mask, nexthop, ifIndex and metric must be supplied 
                     */
                    snmp_log(LOG_ERR,
                             "case COMMIT, can't create without index, mask, nextHop and metric\n");
                    retval = SNMP_ERR_WRONGVALUE;
                }
            }
        }

    case FREE:
        /*
         * Free any resources allocated 
         */
        free(oldroute_row);
        oldroute_row = NULL;
        free(route_row);
        route_row = NULL;
        mask_flag = nexthop_flag = metric_flag = index_flag = dest_flag =
            0;
        break;
    }
    return retval;
}
Ejemplo n.º 3
0
/*
 * Insert a route in the kernel routing table
 * @param destination the route to add
 * @return negative on error
 */
int
os_route_add_rtentry(const struct rt_entry *rt, int ip_version)
{
  MIB_IPFORWARDROW Row;
  union olsr_ip_addr mask;
  unsigned long Res;
  struct interface *iface = rt->rt_best->rtp_nexthop.interface;

  if (AF_INET != ip_version) {
    /*
     * Not implemented
     */
    return -1;
  }


  OLSR_DEBUG(LOG_ROUTING, "KERN: Adding %s\n", olsr_rt_to_string(rt));

  memset(&Row, 0, sizeof(MIB_IPFORWARDROW));

  Row.dwForwardDest = rt->rt_dst.prefix.v4.s_addr;

  if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
    return -1;
  } else {
    Row.dwForwardMask = mask.v4.s_addr;
  }

  Row.dwForwardPolicy = 0;
  Row.dwForwardNextHop = rt->rt_best->rtp_nexthop.gateway.v4.s_addr;
  Row.dwForwardIfIndex = iface->if_index;
  // MIB_IPROUTE_TYPE_DIRECT and MIB_IPROUTE_TYPE_INDIRECT
  Row.dwForwardType = (rt->rt_dst.prefix.v4.s_addr == rt->rt_best->rtp_nexthop.gateway.v4.s_addr) ? 3 : 4;
  Row.dwForwardProto = 3;       // MIB_IPPROTO_NETMGMT
  Row.dwForwardAge = INFINITE;
  Row.dwForwardNextHopAS = 0;
  Row.dwForwardMetric1 = olsr_fib_metric(&rt->rt_best->rtp_metric);
  Row.dwForwardMetric2 = -1;
  Row.dwForwardMetric3 = -1;
  Row.dwForwardMetric4 = -1;
  Row.dwForwardMetric5 = -1;

  Res = SetIpForwardEntry(&Row);

  if (Res != NO_ERROR) {
    if (Res != ERROR_NOT_FOUND)
      OLSR_WARN(LOG_ROUTING, "SetIpForwardEntry() = %08lx, %s", Res, win32_strerror(Res));

    Res = CreateIpForwardEntry(&Row);
  }

  if (Res != NO_ERROR) {
    OLSR_WARN(LOG_ROUTING, "CreateIpForwardEntry() = %08lx, %s", Res, win32_strerror(Res));

    // XXX - report error in a different way

    errno = Res;

    return -1;
  }

  return 0;
}