int upnp_restart(void * pio) { char * cp; NET ifp; int iface; cp = nextarg( ((GEN_IO)pio)->inbuf ); if(!*cp) { ns_printf(pio, "please enter iface to restart UPnP\n"); return -1; } ifp = if_netbytext(pio, cp); if(ifp == NULL) /* error parsing iface name/number text? */ return -1; iface = if_netnumber(ifp); /* skip the DHCP step and go right to autoIP */ upnp[iface].state = UPNP_START; upnp[iface].ip_method = eIP_METHOD_AUTO_FIXED; autoIPs[iface].state = AUTOIP_START; autoIPs[iface].response_timer = 0; autoIPs[iface].arp_attempts = 0; ns_printf(pio, "(re)started UPnP in iface %s\n", ifp->name); return 0; }
static void rtp_fillin(RTMIB rtp, ip_addr dest, ip_addr mask, ip_addr nexthop, struct net * ifp, int prot) { rtp->ipRouteDest = dest; /* fill in entry */ rtp->ipRouteNextHop = nexthop; rtp->ipRouteAge = cticks; /* timestamp it */ rtp->ipRouteProto = prot; /* icmp, or whatever */ rtp->ipRouteMask = mask; rtp->ifp = ifp; /* set the rfc1213 1-based SNMP-ish interface index */ rtp->ipRouteIfIndex = (long)(if_netnumber(ifp)) + 1; if ((dest & mask) == (nexthop & mask)) rtp->ipRouteType = IPRT_DIRECT; else rtp->ipRouteType = IPRT_INDIRECT; rtp->ipRouteMetric1 = ip_mib.ipDefaultTTL; rtp->ipRouteMetric2 = -1; rtp->ipRouteMetric3 = -1; rtp->ipRouteMetric4 = -1; rtp->ipRouteMetric5 = -1; }
int ni_set_state(NET ifp, int opcode) { int err = 0; if ((opcode != NI_DOWN) && (opcode != NI_UP)) { return ENP_PARAM; } LOCK_NET_RESOURCE(NET_RESID); if (opcode == NI_DOWN) /* clean up system tables */ { #ifdef INCLUDE_TCP if_killsocks(ifp); /* kill this iface's sockets */ #endif /* INCLUDE_TCP */ del_route(0, 0, if_netnumber(ifp)); /* delete any IP routes */ clear_arp_entries(NULLIP, ifp); /* delete any ARP entries */ } /* force if-mib AdminStatus flag to correct setting. This will * keep devices without n_setstate() calls from receiving any * packet to send from ip2mac(). */ if (opcode == NI_UP) ifp->n_mib->ifAdminStatus = NI_UP; else ifp->n_mib->ifAdminStatus = NI_DOWN; ifp->n_mib->ifLastChange = cticks * (100/TPS); if (ifp->n_setstate) /* call state routine if any */ err = ifp->n_setstate(ifp, opcode); else err = 0; /* no routine == no error */ if(!err) { /* Get here if setstate was OK - set ifOperStatus */ if (opcode == NI_UP) ifp->n_mib->ifOperStatus = NI_UP; else ifp->n_mib->ifOperStatus = NI_DOWN; } UNLOCK_NET_RESOURCE(NET_RESID); return err; }
int add_share_route(PACKET pkt) { int iface; ip_addr nexthop; RTMIB rt; struct ip * pip; NET ifp; pip = (struct ip * )pkt->nb_prot; rt = rt_lookup(pip->ip_src); ifp = pkt->net; /* net we received packet on */ iface = if_netnumber(ifp); /* We need net index too.... */ /* if we already have a route, just patch the net & return. */ if(rt && (rt->ipRouteDest == pip->ip_src)) { rt->ifp = ifp; return 0; } /* Figure out what to use for a "next hop". If it appears * to be a local IP address, then use the IP address of the * sender; else if there is a route get the GW from that, else if * the iface has one use that. As a last resort, fall back to using * the sender's address as a next hop. */ if((ifp->n_ipaddr & ifp->snmask) == (pip->ip_src & ifp->snmask)) { nexthop = pip->ip_src; } else if(rt) nexthop = rt->ipRouteNextHop; else if(pkt->net->n_defgw) nexthop = ifp->n_defgw; else nexthop = pip->ip_src; /* Now make an explicit route back to the sender */ rt = add_route(pip->ip_src, 0xFFFFFFFF, nexthop, iface, IPRP_OTHER); if(rt) return 0; else return ENP_RESOURCE; }
int upnp_db(void * pio) { char * cp; NET ifp; int iface; ip_addr addr; ip_addr mask; ip_addr gateway; cp = nextarg( ((GEN_IO)pio)->inbuf ); if(!*cp) { ns_printf(pio, "please enter iface for database dump\n"); return -1; } ifp = if_netbytext(pio, cp); if(ifp == NULL) /* error parsing iface name/number text? */ return -1; iface = if_netnumber(ifp); /* Get the fixed IP info from database into tmp vars */ DS_get_long(tag_NET_FIXED_IP, iface, &addr); DS_get_long(tag_NET_FIXED_SUBNET, iface, &mask); DS_get_long(tag_NET_FIXED_GATEWAY, iface, &gateway); ns_printf(pio, "iface:%s; ", ifp->name); ns_printf(pio, " Fixed IP: %u.%u.%u.%u", PUSH_IPADDR(addr) ); ns_printf(pio, " mask: %u.%u.%u.%u", PUSH_IPADDR(mask) ); ns_printf(pio, " gateway: %u.%u.%u.%u\n", PUSH_IPADDR(gateway) ); /* Get the current IP info from database into tmp vars */ DS_get_long(tag_NET_IP_ADDRESS, iface, &addr); DS_get_long(tag_NET_SUBNET, iface, &mask); DS_get_long(tag_NET_GATEWAY, iface, &gateway); ns_printf(pio, "Current ip: %u.%u.%u.%u", PUSH_IPADDR(addr)); ns_printf(pio, " mask: %u.%u.%u.%u", PUSH_IPADDR(mask)); ns_printf(pio, " gateway: %u.%u.%u.%u\n", PUSH_IPADDR(gateway)); return 0; }
int upnp_disable(void * pio) { char * cp; NET ifp; int iface; cp = nextarg( ((GEN_IO)pio)->inbuf ); if(!*cp) { ns_printf(pio, "please enter iface to disable UPnP\n"); return -1; } ifp = if_netbytext(pio, cp); if(ifp == NULL) /* error parsing iface name/number text? */ return -1; iface = if_netnumber(ifp); upnp[iface].state = UPNP_DISABLED; ns_printf(pio, "Disabled UPnP in iface %s\n", ifp->name); return 0; }
RTMIB add_route( ip_addr dest, /* ultimate destination */ ip_addr mask, /* net mask, 0xFFFFFFFF if dest is host address */ ip_addr nexthop, /* where to forward to */ int iface, /* interface (net) for nexthop */ int prot) /* how we know it: icmp, table, etc */ { RTMIB rtp; /* scratch route table entrry pointer */ RTMIB newrt; /* best entry for new route */ struct net * ifp; /* interface (net) for nexthop */ newrt = NULL; /* may be replaced with empty or more expendable entry */ /* set the route interface pointer according to the index passed. This allows * the passed index to be used to access dynamic interfaces, which do not appear * in the nets[] array. */ ifp = if_getbynum(iface); if(!ifp) return NULL; if (rt_mib == NULL) return NULL; /* Don't add null masks or IP addresses - they give false positives on * net matches and don't belong here anyway. */ if((dest == 0) || (mask == 0)) { dtrap(); /* bad configuration? */ dprintf("add_route: rejected null parm; dest: %lx, mask: %lx\n", htonl(dest), htonl(mask) ); return NULL; } /* if it's already in the route table, just update it. */ for (rtp = rt_mib; rtp < rt_mib + ipRoutes; rtp++) { if (rtp->ipRouteDest == dest) /* found existing entry for target */ { rtp->ipRouteNextHop = nexthop; /* fix entry */ rtp->ipRouteAge = cticks; /* timestamp it */ /* set the rfc1213 1-based SNMP-ish interface index */ rtp->ipRouteIfIndex = (long)(iface) + 1; rtp->ipRouteProto = prot; /* icmp, or whatever */ rtp->ipRouteMask = mask; rtp->ifp = ifp; return(rtp); /* just update and exit */ } /* if we didn't find empty slot yet, look for good slot to recycle */ if (!newrt || (newrt->ipRouteProto != 0)) { if (!rtp->ipRouteNextHop) /* found empty slot for use */ { newrt = rtp; /* record empty route for use */ newrt->ipRouteProto = 0; continue; } /* else see if the new route has higher priority than this slot: */ if (rtp_priority[prot] >= rtp_priority[rtp->ipRouteProto]) { if (!newrt) { newrt = rtp; continue; } /* see if rtp is less important then newrtp */ if (rtp_priority[rtp->ipRouteProto] < rtp_priority[newrt->ipRouteProto]) { newrt = rtp; /* save lower priority entry for recycle */ } else if(rtp_priority[rtp->ipRouteProto] == rtp_priority[newrt->ipRouteProto]) { /* if equal priority, keep the older entry for deletion */ if (c_older(rtp->ipRouteAge, newrt->ipRouteAge) == rtp->ipRouteAge) newrt = rtp; /* got an older one */ } } } } /* fall to here if not in table: create a new route */ if (newrt) /* did we find an empty or lower priority route entry? */ rtp = newrt; /* create new entry in lowest priority slot */ else /* all slots have higher priority, new entry looses */ return NULL; /* set default value in new route entry, caller can modiy further. */ rtp->ifp = ifp; rtp->ipRouteDest = dest; rtp->ipRouteIfIndex = (long)(if_netnumber(ifp)) + 1; /* set interface number */ rtp->ipRouteMetric1 = ip_mib.ipDefaultTTL; rtp->ipRouteMetric2 = -1; rtp->ipRouteMetric3 = -1; rtp->ipRouteMetric4 = -1; rtp->ipRouteNextHop = nexthop; rtp->ipRouteProto = prot; /* icmp, or whatever */ if ((dest & mask) == (nexthop & mask)) rtp->ipRouteType = IPRT_DIRECT; else rtp->ipRouteType = IPRT_INDIRECT; rtp->ipRouteAge = cticks; /* timestamp it */ rtp->ipRouteMask = mask; rtp->ipRouteMetric5 = -1; return(rtp); }
/* FUNCTION: netmain_route_add() * * Add IP route table entry * * PARAM1: CLI_CTX CLI context * * RETURNS: int 0 or error code */ STATIC int netmain_route_add(CLI_CTX ctx) { struct cli_addr *cap; ip_addr dst; ip_addr mask; ip_addr nexthop; ip_addr nexthop2; RTMIB rtp; NET ifp; int ifindex; /* extract the destination IP address */ cap = (struct cli_addr *)CLI_VALUE(ctx, 'd'); if (cap->type == CLI_IPV4) { dst = *((ip_addr *)&cap->addr[0]); } else { /* failed to parse destination IP address */ return (CLI_ERR_PARAM); } /* extract the address mask */ cap = (struct cli_addr *)CLI_VALUE(ctx, 'm'); if (cap->type == CLI_IPV4) { mask = *((ip_addr *)&cap->addr[0]); } else { /* failed to parse address mask */ return (CLI_ERR_PARAM); } /* extract the next hop IP address */ cap = (struct cli_addr *)CLI_VALUE(ctx, 'n'); if (cap->type == CLI_IPV4) { nexthop = *((ip_addr *)&cap->addr[0]); } else { /* failed to parse next-hop IPv4 address */ return (CLI_ERR_PARAM); } /* obtain the interface index for the interface where the next hop resides */ ifp = iproute(nexthop, &nexthop2); if (!ifp) { /* can't reach nexthop */ return (CLI_ERR_PARAM); } else { if (nexthop2 != nexthop) { /* nexthop doesn't reside on a directly-connected network */ return (CLI_ERR_PARAM); } ifindex = if_netnumber(ifp); /* add route */ rtp = add_route(dst, mask, nexthop, ifindex, IPRP_LOCAL); if (!rtp) { /* failed to add route */ return (CLI_ERR_EXECUTE); } } return (0); }
void lb_ifsetup(NET netp) { IFMIB mib; netp->n_ipaddr = htonl(0x7f000001); /* 127.0.0.1 */ netp->n_defgw = htonl(0x00000000); netp->snmask = htonl(0xFF000000); netp->n_lnh = ETHHDR_SIZE; /* space reserved for ethernet header */ #ifdef IEEE_802_3 netp->n_lnh += sizeof(struct snap_hdr); /* The bloated version */ #endif netp->n_hal = 6; /* hardware address length */ netp->n_mib->ifType = LOOPIFTYPE; /* * Yes! In Interniche Stack Lingo, MTU for Ethernet II and IEEE 802.3 is * identical. Since the n_mtu field indicates the total frame size sent on * the wire, and not MTU in the usual sense. If things are correctly set up * then (n_mtu - n_lnh) should give us the actual MTU (or the MTU in the * usual sense of the term. */ #ifdef IEEE_802_3 netp->n_mtu = 1514; /* max frame size */ #else netp->n_mtu = 1514; /* max frame size */ #endif if(netp->name[0] == 0) { netp->name[0] = 'l'; netp->name[1] = 'o'; netp->name[2] = (char)('0' + lbnets); } netp->n_flags |= NF_NBPROT; #ifdef IP_V6 { int i; int keepDup; char * cp; netp->n_flags |= NF_IPV6; /* set flag for v6 compatability */ /* set up the standard v6 loopback addresses */ for(i = IPA_LINK; i <= IPA_GLOBAL; i++) { IPV6LOG(("+ lb_ifsetup ip6_dupchecks = %d, i = %d\n", ip6_dupchecks, i)); keepDup = ip6_dupchecks; /* loopback can't affect DAD */ netp->v6addrs[i] = ip6_mkaddr(netp, i, &ip6loopback); ip6_dupchecks = keepDup; netp->v6addrs[i]->prefix = 128; netp->v6addrs[i]->flags = IA_PREFERRED; IPV6LOG(("+ lb_ifsetup 2 ip6_dupchecks = %d, i = %d\n", ip6_dupchecks, i)); cp = (char *)&netp->v6addrs[i]->addr; switch(i) { case IPA_LINK: *cp++ = (char)0xFE; /* paste in the link-local prefix */ *cp = (char)0x80; break; case IPA_SITE: *cp++ = (char)0xFE; /* paste in the site-local prefix */ *cp = (char)0xC0; break; case IPA_GLOBAL: /* leave it all zeros */ break; default: dtrap(); } IPV6DUMP("+ lb_ifsetup addr = \n", (char *)&netp->v6addrs[i]->addr, 16); IPV6LOG(("+ lb_ifsetup netp->v6addrs[i]->flags = %d\n", netp->v6addrs[i]->flags)); } } #endif /* IP_V6 */ /* search the NV parameters for iface setup for our name. If this * fails we just default to what's already in the ifp. */ #ifdef INCLUDE_NVPARMS if_configbyname(netp); #endif #ifdef DYNAMIC_IFACES /* dynamic extensions */ netp->n_setstate = lb_setstate; #endif /* DYNAMIC_IFACES */ mib = netp->n_mib; mib->ifAdminStatus = 2; /* status = down */ mib->ifOperStatus = 2; /* will be set up in init() */ mib->ifLastChange = cticks * (100 / TPS); mib->ifPhysAddress = (u_char *)&lpbhaddr[0]; mib->ifDescr = (u_char *)"loopback (pseudo ethernet)"; mib->ifIndex = if_netnumber(netp); #ifdef IP_V6 /* IPv6 has very specific requirements for loopback behaviour */ mib->ifType = LOOPIFTYPE; #else /* For IPV4 it's convenient to masquerade as ethernet, so we can * test ARP, DHCP, etc., in loopback. */ mib->ifType = ETHERNET; #endif mib->ifSpeed = 10000000; mib->ifMtu = 1500; /* ethernetish default */ /* install our hardware driver routines */ netp->n_init = lb_init; #ifdef LB_RAW_SEND netp->raw_send = lb_raw_send; #else /* use packet send */ netp->pkt_send = lb_pkt_send; #endif /* LB_RAW_SEND */ netp->n_close = lb_close; netp->n_stats = lb_stats; }