Esempio n. 1
0
int do_tests(unsigned char *ifname, Boolean do_set_tests, Boolean use_ipv6)
{
    unsigned char default_ifname[16] = DEFAULT_IFNAME;
    SshUInt32 ifnum, flags;
    SshNetconfigError error;
    unsigned char addr_buf[64], mask_buf[64];
    SshNetconfigLinkStruct link;
    SshNetconfigInterfaceAddrStruct address;
    SshNetconfigRouteStruct route;
    Boolean use_any_interface;
    unsigned char print_buf[512];

    if (ifname == NULL)
    {
        use_any_interface = TRUE;
        ifname = default_ifname;
    }
    else
    {
        use_any_interface = FALSE;
    }
    ifnum = SSH_INVALID_IFNUM;

    /* Resolve ifname. */
    printf("Resolving interface \"%s\": ", ifname);
    error = ssh_netconfig_resolve_ifname(ifname, &ifnum);
    if (error != SSH_NETCONFIG_ERROR_OK)
        printf("ssh_netconfig_resolve_ifname: error %d\n", error);
    else
        printf("ifnum %ld\n", ifnum);

    if (ifnum == SSH_INVALID_IFNUM)
    {
        if (use_any_interface)
        {
            /* Pick another interface. */
            for (ifnum = 10; ifnum >= 1; ifnum--)
            {
                printf("Resolving ifnum %d: ", (int) ifnum);
                if (ssh_netconfig_resolve_ifnum(ifnum, default_ifname,
                                                sizeof(default_ifname))
                        == SSH_NETCONFIG_ERROR_OK)
                {
                    ifname = default_ifname;
                    printf("\"%s\"\n", ifname);
                    goto interface_found;
                }
                printf("not found\n");
            }
            printf("no usable interfaces found\n");
        }
        return -1;
    }

interface_found:

    /* Get link state. */
    printf("Fetching link state: ");
    error = ssh_netconfig_get_link(ifnum, &link);
    if (error != SSH_NETCONFIG_ERROR_OK)
    {
        printf("ssh_netconfig_get_link: error %d\n", error);
        return -1;
    }
    if (ssh_snprintf(print_buf, sizeof(print_buf),
                     "%@", ssh_netconfig_link_render, &link)
            <= sizeof(print_buf))
        printf("%s\n", print_buf);

    /* Set link state up. */
    if (do_set_tests)
    {
        /* Bring link up, even if it is already up, because this
        is a test program. */
        printf("Bringing interface up: ");
        error = ssh_netconfig_set_link_flags(ifnum, SSH_NETCONFIG_LINK_UP,
                                             SSH_NETCONFIG_LINK_UP);
        if (error != SSH_NETCONFIG_ERROR_OK)
        {
            printf("ssh_netconfig_set_link_flags: error %d\n", error);
            return -1;
        }
        printf("ok\n");
    }

    /* Dump addresses. */
    printf("Fetching addresses:\n");
    if (dump_addresses(ifnum))
        return -1;


    if (do_set_tests)
    {
        /* Add new IP address. */
        memset(&address, 0, sizeof(address));
        if (!use_ipv6)
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_ADDR);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV4_MASK);
        }
        else
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV6_ADDR);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV6_MASK);
        }
        printf("Adding address %s/%s ", addr_buf, mask_buf);
        if (!ssh_ipaddr_parse_with_mask(&address.address, addr_buf, mask_buf))
        {
            printf("ssh_ipaddr_parse: error\n");
            return -1;
        }
        if (!use_ipv6)
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_BCAST);
            printf("brd %s: ", addr_buf);
            if (!ssh_ipaddr_parse(&address.broadcast, addr_buf))
            {
                printf("ssh_ipaddr_parse: error\n");
                return -1;
            }
            address.flags = SSH_NETCONFIG_ADDR_BROADCAST;
        }
        error = ssh_netconfig_add_address(ifnum, &address);
        if (error != SSH_NETCONFIG_ERROR_OK)
        {
            printf("ssh_netconfig_add_address: error %d\n", error);
            return -1;
        }
        printf("ok\n");

        /* Dump addresses. */
        printf("Fetching addresses:\n");
        if (dump_addresses(ifnum))
            return -1;
    }


    /* Dump routes. */
    printf("Fetching routing table:\n");
    if (dump_routes(NULL))
        return -1;


    if (do_set_tests)
    {
        /* Add new route. */
        memset(&route, 0, sizeof(route));
        if (!use_ipv6)
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_NET);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV4_NETMASK);
        }
        else
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV6_NET);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV6_NETMASK);
        }
        ssh_ipaddr_parse_with_mask(&route.prefix, addr_buf, mask_buf);
        printf("Adding route %s/%s", addr_buf, mask_buf);
        if (!use_ipv6)
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_GW);
        else
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV6_GW);
        ssh_ipaddr_parse(&route.gateway, addr_buf);
        route.ifnum = ifnum;
        route.metric = 8;
        printf(" via %s dev %ld metric %ld: ",
               addr_buf, route.ifnum, route.metric);
        error = ssh_netconfig_add_route(&route);
        if (error != SSH_NETCONFIG_ERROR_OK)
        {
            printf("ssh_netconfig_add_route: error %d\n", error);
            return -1;
        }
        printf("ok\n");


        /* Dump routes. */
        printf("Fetching routing table:\n");
        if (dump_routes(NULL))
            return -1;

    }


    /* Get routes matching prefix. */
    if (!use_ipv6)
    {
        ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_NET);
        ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV4_NETMASK);
    }
    else
    {
        ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV6_NET);
        ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV6_NETMASK);
    }
    printf("Getting routes matching %s/%s:\n", addr_buf, mask_buf);
    ssh_ipaddr_parse_with_mask(&route.prefix, addr_buf, mask_buf);
    if (dump_routes(&route.prefix))
        return -1;


    if (do_set_tests)
    {
        /* Delete newly added route. */
        memset(&route, 0, sizeof(route));
        if (!use_ipv6)
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_NET);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV4_NETMASK);
        }
        else
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV6_NET);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV6_NETMASK);
        }
        ssh_ipaddr_parse_with_mask(&route.prefix, addr_buf, mask_buf);
        printf("Deleting route %s/%s", addr_buf, mask_buf);
        if (!use_ipv6)
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_GW);
        else
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV6_GW);
        ssh_ipaddr_parse(&route.gateway, addr_buf);
        route.ifnum = ifnum;
        route.metric = 8;
        printf(" via %s dev %ld metric %ld: ",
               addr_buf, route.ifnum, route.metric);
        error = ssh_netconfig_del_route(&route);
        if (error != SSH_NETCONFIG_ERROR_OK)
        {
            printf("ssh_netconfig_del_route: error %d\n", error);
            return -1;
        }
        printf("ok\n");


        /* Dump routes. */
        printf("Fetching routing table:\n");
        if (dump_routes(NULL))
            return -1;


        /* Delete newly added address. */
        memset(&address, 0, sizeof(address));
        if (!use_ipv6)
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV4_ADDR);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV4_MASK);
        }
        else
        {
            ssh_snprintf(addr_buf, sizeof(addr_buf), DEFAULT_IPV6_ADDR);
            ssh_snprintf(mask_buf, sizeof(mask_buf), DEFAULT_IPV6_MASK);
        }
        printf("Deleting address %s/%s: ", addr_buf, mask_buf);
        if (!ssh_ipaddr_parse_with_mask(&address.address, addr_buf, mask_buf))
        {
            printf("ssh_ipaddr_parse: error\n");
            return -1;
        }
        address.flags = 0;
        error = ssh_netconfig_del_address(ifnum, &address);
        if (error != SSH_NETCONFIG_ERROR_OK)
        {
            printf("ssh_netconfig_del_address: error %d\n", error);
            return -1;
        }
        printf("ok\n");


        /* Dump addresses. */
        printf("Fetching addresses:\n");
        if (dump_addresses(ifnum))
            return -1;

        /* Restore link state. */
        if ((flags & SSH_NETCONFIG_LINK_UP) == 0)
        {
            printf("Bringing interface down: ");
            error =
                ssh_netconfig_set_link_flags(ifnum, 0, SSH_NETCONFIG_LINK_UP);
            if (error != SSH_NETCONFIG_ERROR_OK)
            {
                printf("ssh_netconfig_set_link_flags: error %d\n", error);
                return -1;
            }
            printf("ok\n");
        }
    }

    return 0;
}
Esempio n. 2
0
int main(int argc, char **argv)
{

  struct packet {
    unsigned long word1;
    unsigned long word2;
    unsigned long word3;
    unsigned long src_addr;
    unsigned long dst_addr;
    unsigned char rest[8172];
  };

  int addrlen;
  int fd;
  int i;
  int n;
  struct packet packet;
  struct route *rp;
  struct sockaddr_in addr;

  if (argc >= 2) {
    load_routes();
    dump_routes();
    exit(0);
  }

  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    halt("socket");
  memset((char *) &addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(PORT);
  if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)))
    halt("bind");
  for (n = 0; n < 60; n++) {
    if (n != fd)
      close(n);
  }
  if (fork())
    exit(0);
  setsid();
  if (fork())
    exit(0);
  load_routes();
  for (;;) {
    addrlen = sizeof(addr);
    n = recvfrom(fd, (char *) &packet, sizeof(struct packet), 0, (struct sockaddr *) &addr, &addrlen);
    if (n < 20)
      continue;
    i = (int) (packet.src_addr & 0xff);
    for (rp = Routes[i]; rp && rp->a_addr != packet.src_addr; rp = rp->next) ;
    if (!rp) {
      rp = (struct route *) malloc(sizeof(struct route));
      if (rp) {
	rp->a_addr = packet.src_addr;
	rp->i_addr = 0;
	rp->i_port = 0;
	rp->next = Routes[i];
	Routes[i] = rp;
      }
    }
    if (rp &&
	(rp->i_addr != addr.sin_addr.s_addr ||
	 rp->i_port != addr.sin_port)) {
      rp->i_addr = addr.sin_addr.s_addr;
      rp->i_port = addr.sin_port;
      save_routes();
    }
    i = (int) (packet.dst_addr & 0xff);
    for (rp = Routes[i]; rp && rp->a_addr != packet.dst_addr; rp = rp->next) ;
    if (!rp)
      rp = find_subnet_route(packet.dst_addr);
    if (rp) {
      addr.sin_addr.s_addr = rp->i_addr;
      addr.sin_port = rp->i_port;
      sendto(fd, (char *) &packet, n, 0, (struct sockaddr *) &addr, sizeof(addr));
    }
  }
}