/* * Handler for the connection "route" command * route show * route add -dev eth0|tap0 -net nw_addr -netmask mask [-gw gw_addr] * route del route_number */ void routeCmd() { char *next_tok; char tmpbuf[MAX_TMPBUF_LEN]; uchar net_addr[4], net_mask[4], nxth_addr[4]; int interface, del_route; char dev_name[MAX_DNAME_LEN]; // set defaults for optional parameters bzero(nxth_addr, 4); next_tok = strtok(NULL, " \n"); if (next_tok != NULL) { if (!strcmp(next_tok, "add")) { GET_NEXT_PARAMETER("-dev", "route:: missing device name .."); strcpy(dev_name, next_tok); interface = gAtoi(next_tok); GET_NEXT_PARAMETER("-net", "route:: missing network address .."); Dot2IP(next_tok, net_addr); GET_NEXT_PARAMETER("-netmask", "route:: missing netmask .."); Dot2IP(next_tok, net_mask); verbose(2, "[routeCmd]:: Device %s Interface %d, net_addr %s, netmask %s ", dev_name, interface, IP2Dot(tmpbuf, net_addr), IP2Dot((tmpbuf+20), net_mask)); if (((next_tok = strtok(NULL, " \n")) != NULL) && (!strcmp("-gw", next_tok))) { next_tok = strtok(NULL, " \n"); Dot2IP(next_tok, nxth_addr); } addRouteEntry(route_tbl, net_addr, net_mask, nxth_addr, interface); } else if (!strcmp(next_tok, "del")) { next_tok = strtok(NULL, " \n"); del_route = gAtoi(next_tok); deleteRouteEntryByIndex(route_tbl, del_route); } else if (!strcmp(next_tok, "show")) printRouteTable(route_tbl); } return; }
void pingCmd() { char *next_tok = strtok(NULL, " \n"); int tries, pkt_size; uchar ip_addr[4]; char tmpbuf[MAX_TMPBUF_LEN]; if (next_tok == NULL) return; if (next_tok[0] == '-') { tries = gAtoi(next_tok); next_tok = strtok(NULL, " \n"); } else tries = 1; Dot2IP(next_tok, ip_addr); verbose(2, "[pingCmd]:: ping command sent, tries = %d, IP = %s", tries, IP2Dot(tmpbuf, ip_addr)); if ((next_tok = strtok(NULL, " \n")) != NULL) { if (!strcmp(next_tok, "-size")) { next_tok = strtok(NULL, " \n"); pkt_size = atoi(next_tok); } else pkt_size = 64; } else pkt_size = 64; ICMPDoPing(ip_addr, pkt_size, tries); }
/* * ARGUMENTS: device: e.g. tun2 * mac_addr: hardware address of the interface * nw_addr: network address of the interface (IPv4 by default) * dst_ip: physical IP address of destination mesh station on the MBSS * dst_port: interface number of the destination interface on the destination yRouter * RETURNS: a pointer to the interface on success and NULL on failure */ interface_t *GNETMakeTunInterface(char *device, uchar *mac_addr, uchar *nw_addr, uchar* dst_ip, short int dst_port) { vpl_data_t *vcon; interface_t *iface; int iface_id; char tmpbuf[MAX_TMPBUF_LEN]; verbose(2, "[GNETMakeTunInterface]:: making Interface for [%s] with MAC %s and IP %s", device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr)); iface_id = gAtoi(device); if (findInterface(iface_id) != NULL) { verbose(1, "[GNETMakeTunInterface]:: device %s already defined.. ", device); return NULL; } // setup the interface.. iface = newInterfaceStructure(device, device, mac_addr, nw_addr, MAX_MTU); verbose(2, "[GNETMakeTunInterface]:: trying to connect to %s..", device); vcon = tun_connect((short int)(BASEPORTNUM+iface_id+gAtoi(rconfig.router_name)*100), NULL, (short int)(BASEPORTNUM+dst_port+gAtoi(rconfig.router_name)*100), dst_ip); if(vcon == NULL) { verbose(1, "[GNETMakeTunInterface]:: unable to connect to %s", device); return NULL; } iface->iface_fd = vcon->data; iface->vpl_data = vcon; upThisInterface(iface); return iface; }
interface_t *GNETMakeTapInterface(char *device, uchar *mac_addr, uchar *nw_addr) { vpl_data_t *vcon; interface_t *iface; int iface_id; char tmpbuf[MAX_TMPBUF_LEN]; verbose(2, "[GNETMakeTapInterface]:: making Interface for [%s] with MAC %s and IP %s", device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr)); iface_id = gAtoi(device); if (findInterface(iface_id) != NULL) { verbose(1, "[GNETMakeTapInterface]:: device %s already defined.. ", device); return NULL; } else { // setup the interface.. with default MTU of 1500 we cannot set it at this time. iface = newInterfaceStructure(device, device, mac_addr, nw_addr, 1500); /* * try connection (as client). only option here... */ verbose(2, "[GNETMakeTapInterface]:: trying to connect to %s..", device); if ((vcon = tap_connect(device)) == NULL) { verbose(1, "[GNETMakeTapInterface]:: unable to connect to %s", device); return NULL; } // fill in the rest of the interface iface->iface_fd = vcon->data; iface->vpl_data = vcon; upThisInterface(iface); return iface; } }
void setupProgram(int ac, char *av[]) { int indx; prog_init(); prog_set_syntax("[options] router_name"); prog_set_options(options); prog_set_version("2.1"); prog_set_date("20091024"); prog_set_author("Muthucumaru Maheswaran <*****@*****.**>"); prog_set_contact(prog_author()); prog_set_url("http://www.cs.mcgill.ca/~anrl/gini/"); prog_set_desc("GINI router provides a user-space IP router for teaching and learning purposes."); prog_set_verbosity_level(1); indx = prog_opt_process(ac, av); if (indx < ac) rconfig.router_name = strdup(av[indx]); if (rconfig.router_name == NULL) { prog_usage_msg("\n[setupProgram]:: Router name missing.. \n\n"); exit(1); } prog_set_name(rconfig.router_name); rconfig.gini_home = getenv("GINI_HOME"); if (rconfig.gini_home == NULL) { verbose(2, "\n[setupProgram]:: Environment variable GINI_HOME is not set..\n\n"); rconfig.gini_home = "~/Desktop/Grouter/"; exit(1); } rconfig.top_num = gAtoi(rconfig.router_name); }
/* * Create an interface data structure and fill it with relevant information. * This routine does not setup any external elements.. other than finding * the device driver and linking it. We need the correct device driver for * the interface.. because a particular device would provide its own I/O routines. */ interface_t *newInterfaceStructure(char *vsock_name, char *device, uchar *mac_addr, uchar *nw_addr, int iface_mtu) { int iface_id; interface_t *iface; iface_id = gAtoi(device); // fill in the interface structure... iface = (interface_t *) malloc(sizeof(interface_t)); if (iface == NULL) { fatal("[createInterfaceStructure]:: Memory allocation error "); return NULL; } verbose(2, "[createInterfaceStructure]:: Memory allocated for interface structure "); bzero((void *)iface, sizeof(interface_t)); iface->interface_id = iface_id; iface->mode = IFACE_CLIENT_MODE; iface->state = INTERFACE_DOWN; // start in the DOWN state sscanf(device, "%[a-z]", iface->device_type); strcpy(iface->device_name, device); strcpy(iface->sock_name, vsock_name); COPY_MAC(iface->mac_addr, mac_addr); COPY_IP(iface->ip_addr, nw_addr); iface->device_mtu = iface_mtu; verbose(2, "[makeInterface]:: Searching the device driver for %s ", iface->device_type); iface->devdriver = findDeviceDriver(iface->device_type); iface->iarray = &netarray; return iface; }
/* * class add class_name [-src ( packet spec )] [-dst ( packet spec )] * class del class_name * class show * packet_spec = -net ipaddr/prevlen -port lower-upper -prot number */ void classCmd() { char *next_tok; char tmpbuf[MAX_TMPBUF_LEN]; char cname[MAX_DNAME_LEN]; int sside; ip_spec_t *ips; port_range_t *pps; next_tok = strtok(NULL, " \n"); if (next_tok != NULL) { if (!strcmp(next_tok, "add")) { next_tok = strtok(NULL, " \n"); strcpy(cname, next_tok); addClassDef(classifier, cname); while ((next_tok = strtok(NULL, " \n")) != NULL) { if (!strcmp(next_tok, "-src")) sside = 1; if (!strcmp(next_tok, "-dst")) sside = 0; while ((next_tok = strtok(NULL, "( )\n")) != NULL) { if (!strcmp(next_tok, "-net")) { next_tok = strtok(NULL, " )\n"); ips = parseIPSpec(next_tok); insertIPSpec(classifier, cname, sside, ips); } if (!strcmp(next_tok, "-port")) { next_tok = strtok(NULL, " )\n"); pps = parsePortRangeSpec(next_tok); insertPortRangeSpec(classifier, cname, sside, pps); } if (!strcmp(next_tok, "-prot")) { next_tok = strtok(NULL, " )\n"); insertProtSpec(classifier, cname, gAtoi(next_tok)); } if (!strcmp(next_tok, "-tos")) { next_tok = strtok(NULL, " )\n"); insertTOSSpec(classifier, cname, gAtoi(next_tok)); } } } } else if (!strcmp(next_tok, "del")) { next_tok = strtok(NULL, " \n"); if (next_tok != NULL) { strcpy(cname, next_tok); delClassDef(classifier, cname); } } else if (!strcmp(next_tok, "show")) printClassifier(classifier); } return; }
/* * Handler for the interface configuration command: * ifconfig add eth1 -socket socketfile -addr IP_addr -hwaddr MAC [-gateway GW] [-mtu N] * ifconfig add tap0 -device dev_location -addr IP_addr -hwaddr MAC * ifconfig add tun0 -dstip dst_ip -dstport portnum -addr IP_addr -hwaddr MAC * ifconfig del eth0|tap0 * ifconfig show [brief|verbose] * ifconfig up eth0|tap0 * ifconfig down eth0|tap0 * ifconfig mod eth0 (-gateway GW | -mtu N) */ void ifconfigCmd() { char *next_tok; interface_t *iface; char dev_name[MAX_DNAME_LEN], con_sock[MAX_NAME_LEN], dev_type[MAX_NAME_LEN]; uchar mac_addr[6], ip_addr[4], gw_addr[4], dst_ip[4]; int mtu, interface, mode; short int dst_port; // set default values for optional parameters bzero(gw_addr, 4); mtu = DEFAULT_MTU; mode = NORMAL_LISTING; // we have already matched ifconfig... now parsing rest of the parameters. next_tok = strtok(NULL, " \n"); if (next_tok == NULL) { printf("[ifconfigCmd]:: missing action parameter.. type help ifconfig for usage.\n"); return; } if (!strcmp(next_tok, "add")) { next_tok = strtok(NULL, " \n"); if ( (next_tok == NULL) || (findDeviceDriver(next_tok) == NULL) ) { printf("ifconfig:: missing or invalid interface spec ..\n"); return; } strcpy(dev_name, next_tok); sscanf(dev_name, "%[a-z]", dev_type); interface = gAtoi(dev_name); if ((interface == 0) && (strcmp(dev_type, "eth") == 0)) { printf("[ifconfigCmd]:: device number 0 is reserved for tap - start from 1\n"); return; } if (strcmp(dev_type, "eth") == 0) { GET_NEXT_PARAMETER("-socket", "ifconfig:: missing -socket spec .."); strcpy(con_sock, next_tok); } else if(strcmp(dev_type, "tun") == 0) { GET_NEXT_PARAMETER("-dstip", "ifconfig:: missing -dstip spec .."); Dot2IP(next_tok, dst_ip); GET_NEXT_PARAMETER("-dstport", "ifconfig:: missing -dstport spec .."); dst_port = (short int)atoi(next_tok); } GET_NEXT_PARAMETER("-addr", "ifconfig:: missing -addr spec .."); Dot2IP(next_tok, ip_addr); GET_NEXT_PARAMETER("-hwaddr", "ifconfig:: missing -hwaddr spec .."); Colon2MAC(next_tok, mac_addr); while ((next_tok = strtok(NULL, " \n")) != NULL) if (!strcmp("-gateway", next_tok)) { next_tok = strtok(NULL, " \n"); Dot2IP(next_tok, gw_addr); } else if (!strcmp("-mtu", next_tok)) { next_tok = strtok(NULL, " \n"); mtu = atoi(next_tok); } if (strcmp(dev_type, "eth") == 0) iface = GNETMakeEthInterface(con_sock, dev_name, mac_addr, ip_addr, mtu, 0); else if (strcmp(dev_type, "tap") == 0) iface = GNETMakeTapInterface(dev_name, mac_addr, ip_addr); else if (strcmp(dev_type, "tun") == 0) iface = GNETMakeTunInterface(dev_name, mac_addr, ip_addr, dst_ip, dst_port); else { printf("[ifconfigCmd]:: Unkown device type %s\n", dev_type); return; } if (iface != NULL) { verbose(2, "[configureInterfaces]:: Inserting the definition in the interface table "); GNETInsertInterface(iface); addMTUEntry(MTU_tbl, iface->interface_id, iface->device_mtu, iface->ip_addr); // for tap0 interface the MTU value cannot be changed. should we allow change? } } else if (!strcmp(next_tok, "del")) { GET_THIS_OR_THIS_PARAMETER("eth", "tap", "ifconfig:: missing interface spec .."); strcpy(dev_name, next_tok); interface = gAtoi(next_tok); destroyInterfaceByIndex(interface); deleteMTUEntry(interface); } else if (!strcmp(next_tok, "up")) { GET_THIS_OR_THIS_PARAMETER("eth", "tap", "ifconfig:: missing interface spec .."); strcpy(dev_name, next_tok); interface = gAtoi(next_tok); upInterface(interface); } else if (!strcmp(next_tok, "down")) { GET_THIS_OR_THIS_PARAMETER("eth", "tap", "ifconfig:: missing interface spec .."); strcpy(dev_name, next_tok); interface = gAtoi(next_tok); downInterface(interface); } else if (!strcmp(next_tok, "mod")) { GET_THIS_PARAMETER("eth", "ifconfig:: missing interface spec .."); strcpy(dev_name, next_tok); interface = gAtoi(next_tok); while ((next_tok = strtok(NULL, " \n")) != NULL) if (!strcmp("-gateway", next_tok)) { next_tok = strtok(NULL, " \n"); strcpy(gw_addr, next_tok); } else if (!strcmp("-mtu", next_tok)) { next_tok = strtok(NULL, " \n"); mtu = atoi(next_tok); } changeInterfaceMTU(interface, mtu); } else if (!strcmp(next_tok, "show")) { if ((next_tok = strtok(NULL, " \n")) != NULL) { if (strstr(next_tok, "bri") != NULL) mode = BRIEF_LISTING; else if (strstr(next_tok, "verb") != NULL) mode = VERBOSE_LISTING; } else mode = NORMAL_LISTING; printInterfaces(mode); } return; }
interface_t *GNETMakeEthInterface(char *vsock_name, char *device, uchar *mac_addr, uchar *nw_addr, int iface_mtu, int cforce) { vpl_data_t *vcon; interface_t *iface; int iface_id, thread_stat; char tmpbuf[MAX_TMPBUF_LEN]; vplinfo_t *vi; pthread_t threadid; verbose(2, "[GNETMakeEthInterface]:: making Interface for [%s] with MAC %s and IP %s", device, MAC2Colon(tmpbuf, mac_addr), IP2Dot((tmpbuf+20), nw_addr)); iface_id = gAtoi(device); if (findInterface(iface_id) != NULL) { verbose(1, "[GNETMakeEthInterface]:: device %s already defined.. ", device); return NULL; } else { // setup the interface.. iface = newInterfaceStructure(vsock_name, device, mac_addr, nw_addr, iface_mtu); /* * try connection (as client). if it fails and force client flag * is set, then return NULL. Otherwise, try server connection, * if this fails, print error and return NULL */ verbose(2, "[GNETMakeEthInterface]:: trying to connect to %s..", vsock_name); if ((vcon = vpl_connect(vsock_name)) == NULL) { verbose(2, "[GNETMakeEthInterface]:: connecting as server.. "); // if client mode is forced.. fail here.. cannot do much! if (cforce) { verbose(1, "[GNETMakeEthInterface]:: unable to make network connection..."); return NULL; } // try making a server connection... // now that the client connection has failed if ((vcon = vpl_create_server(vsock_name)) == NULL) { verbose(1, "[GNETMakeEthInterface]:: unable to make server connection.. "); return NULL; } vi = (vplinfo_t *)malloc(sizeof(vplinfo_t)); iface->mode = IFACE_SERVER_MODE; vi->vdata = vcon; vi->iface = iface; thread_stat = pthread_create(&(iface->sdwthread), NULL, (void *)delayedServerCall, (void *)vi); if (thread_stat != 0) return NULL; // return for now.. the thread spawned above will change the // interface state when the remote node makes the connection. return iface; } verbose(2, "[GNETMakeEthInterface]:: VPL connection made as client "); // fill in the rest of the interface iface->iface_fd = vcon->data; iface->vpl_data = vcon; upThisInterface(iface); return iface; } }