示例#1
0
int main(int argc, char *argv[])
{
	in_addr_t	dst_ip;
	unsigned char	*mac;
	in_addr_t	ip;
	int		chkip;

	if ( argc < 2 ) {
		printf("too few argument\n");
		exit(-1);
	}
	dst_ip = inet_addr(argv[1]);
	mac = (char*)malloc(16);
	get_if_info("eth0", mac, &ip);

	chkip = check_ip("eth0", dst_ip);
	if ( chkip < 0 ){
		printf("check_ip error\n");
		return -1;
	}else if ( chkip == 0 ) 
		printf("IP free\n");
	else
		printf("IP has been used\n");

	return 0;
}
示例#2
0
int mcast::get_if_list(if_info* ifi,int nifi)
{
    int s=socket(PF_INET,SOCK_DGRAM,0);

    int n=0;

    if(s!=-1)
    {
        int l=sizeof(ifreq)*nifi;

        ifreq* ifr=(ifreq*)MALLOC(l);

        if(ifi)
        {
            ifconf ifc;

            memset((char*)&ifc,0,sizeof(ifc));

            ifc.ifc_buf=(char*)ifr;
            ifc.ifc_len=l;

            if(ioctl(s,SIOCGIFCONF,&ifc)!=-1)
            {
                n=ifc.ifc_len/sizeof(ifreq);
                if(n>nifi)
                    n=nifi;

                for(int i=0;i<n;i++)
                {
#ifdef __FreeBSD__
                    get_if_info(ifr[i].ifr_name,ifi+i);
#else
                    get_if_info(ifr[i].ifr_ifrn.ifrn_name,ifi+i);
#endif /* __FreeBSD__ */
                }
            }

            FREE(ifr);
        }

        close(s);
    }

    return n;
}
示例#3
0
文件: dladm.c 项目: andreiw/polaris
/* ARGSUSED */
static void
show_link(void *arg, const char *name)
{
	dladm_attr_t	dlattr;
	boolean_t	legacy = B_TRUE;
	show_link_state_t *state = (show_link_state_t *)arg;

	if (get_if_info(name, &dlattr, &legacy) < 0) {
		(void) fprintf(stderr, gettext("%s: invalid device '%s'\n"),
		    progname, name);
		exit(1);
	}

	if (state->ls_parseable) {
		print_link_parseable(name, &dlattr, legacy);
	} else {
		print_link(name, &dlattr, legacy);
	}
}
示例#4
0
文件: dladm.c 项目: andreiw/polaris
/* ARGSUSED */
static void
link_stats(const char *link, uint32_t interval)
{
	dladm_attr_t		dlattr;
	boolean_t		legacy;
	show_link_state_t	state;

	if (link != NULL && get_if_info(link, &dlattr, &legacy) < 0) {
		(void) fprintf(stderr, gettext("%s: invalid device '%s'\n"),
		    progname, link);
		exit(1);
	}
	bzero(&state, sizeof (state));

	/*
	 * If an interval is specified, continuously show the stats
	 * only for the first MAC port.
	 */
	state.ls_firstonly = (interval != 0);

	for (;;) {
		(void) printf("\t\tipackets  rbytes	 ierrors ");
		(void) printf("opackets	 obytes	     oerrors\n");

		state.ls_donefirst = B_FALSE;
		if (link == NULL)
			(void) dladm_walk(show_link_stats, &state);
		else
			show_link_stats(&state, link);

		if (interval == 0)
			break;

		(void) sleep(interval);
	}
}
示例#5
0
文件: main.c 项目: azhgul/AODV-1
void host_init(char *ifname)
{
    struct sockaddr_in *ina;
    char buf[1024], tmp_ifname[IFNAMSIZ],
	ifnames[(IFNAMSIZ + 1) * MAX_NR_INTERFACES], *iface;
    struct ifconf ifc;
    struct ifreq ifreq, *ifr;
    int i, iw_sock, if_sock = 0;

    memset(&this_host, 0, sizeof(struct host_info));
    memset(dev_indices, 0, sizeof(unsigned int) * MAX_NR_INTERFACES);

    if (!ifname) {
	/* No interface was given... search for first wireless. */
	iw_sock = socket(PF_INET, SOCK_DGRAM, 0);
	ifc.ifc_len = sizeof(buf);
	ifc.ifc_buf = buf;
	if (ioctl(iw_sock, SIOCGIFCONF, &ifc) < 0) {
	    fprintf(stderr, "Could not get wireless info\n");
	    exit(-1);
	}
	ifr = ifc.ifc_req;
	for (i = ifc.ifc_len / sizeof(struct ifreq); i >= 0; i--, ifr++) {
	    struct iwreq req;

	    strcpy(req.ifr_name, ifr->ifr_name);
	    if (ioctl(iw_sock, SIOCGIWNAME, &req) >= 0) {
		strcpy(tmp_ifname, ifr->ifr_name);
		break;
	    }
	}
	/* Did we find a wireless interface? */
	if (!strlen(tmp_ifname)) {
	    fprintf(stderr, "\nCould not find a wireless interface!\n");
	    fprintf(stderr, "Use -i <interface> to override...\n\n");
	    exit(-1);
	}
	strcpy(ifreq.ifr_name, tmp_ifname);
	if (ioctl(iw_sock, SIOCGIFINDEX, &ifreq) < 0) {
	    alog(LOG_ERR, errno, __FUNCTION__,
		 "Could not get index of %s", tmp_ifname);
	    close(if_sock);
	    exit(-1);
	}
	close(iw_sock);

	ifname = tmp_ifname;

	alog(LOG_NOTICE, 0, __FUNCTION__,
	     "Attaching to %s, override with -i <if1,if2,...>.", tmp_ifname);
    }

    strcpy(ifnames, ifname);

    /* Intitialize the local sequence number an rreq_id to zero */
    this_host.seqno = 1;
    this_host.rreq_id = 0;

    /* Zero interfaces enabled so far... */
    this_host.nif = 0;

    gettimeofday(&this_host.bcast_time, NULL);

    /* Find the indices of all interfaces to broadcast on... */
    if_sock = socket(AF_INET, SOCK_DGRAM, 0);

    iface = strtok(ifname, ",");

    /* OK, now lookup interface information, and store it... */
    do {
	strcpy(ifreq.ifr_name, iface);
	if (ioctl(if_sock, SIOCGIFINDEX, &ifreq) < 0) {
	    alog(LOG_ERR, errno, __FUNCTION__, "Could not get index of %s",
		 iface);
	    close(if_sock);
	    exit(-1);
	}
	this_host.devs[this_host.nif].ifindex = ifreq.ifr_ifindex;

	dev_indices[this_host.nif++] = ifreq.ifr_ifindex;

	strcpy(DEV_IFINDEX(ifreq.ifr_ifindex).ifname, iface);

	/* Get IP-address of interface... */
	ina = get_if_info(iface, SIOCGIFADDR);

	if (ina == NULL)
	    exit(-1);

	DEV_IFINDEX(ifreq.ifr_ifindex).ipaddr = ina->sin_addr;

	/* Get netmask of interface... */
	ina = get_if_info(iface, SIOCGIFNETMASK);

	if (ina == NULL)
	    exit(-1);

	DEV_IFINDEX(ifreq.ifr_ifindex).netmask = ina->sin_addr;

	ina = get_if_info(iface, SIOCGIFBRDADDR);

	if (ina == NULL)
	    exit(-1);

	DEV_IFINDEX(ifreq.ifr_ifindex).broadcast = ina->sin_addr;

	DEV_IFINDEX(ifreq.ifr_ifindex).enabled = 1;

	if (this_host.nif >= MAX_NR_INTERFACES)
	    break;

    } while ((iface = strtok(NULL, ",")));

    close(if_sock);

    /* Load kernel modules */
    load_modules(ifnames);

    /* Enable IP forwarding and set other kernel options... */
    if (set_kernel_options() < 0) {
	fprintf(stderr, "Could not set kernel options!\n");
	exit(-1);
    }
}
示例#6
0
文件: ifutil.c 项目: aosm/bootp
PRIVATE_EXTERN void
inet6_addrlist_copy(inet6_addrlist_t * addr_list_p, int if_index)
{
    int				addr_index = 0;
    char *			buf = NULL;
    char *			buf_end;
    int				buf_len;
    int				count;
    int				error;
    int				i;
    char			ifname[IFNAMSIZ + 1];
    inet6_addrinfo_t *		linklocal = NULL;
    inet6_addrinfo_t *		list = NULL;
    char *			scan;
    struct rt_msghdr *		rtm;
    int				s = -1;

    buf = get_if_info(if_index, AF_INET6, &buf_len);
    if (buf == NULL) {
	goto done;
    }
    buf_end = buf + buf_len;

    /* figure out how many IPv6 addresses there are */
    count = 0;
    ifname[0] = '\0';
    for (scan = buf; scan < buf_end; scan += rtm->rtm_msglen) {
	struct if_msghdr * 	ifm;
	
	/* ALIGN: buf aligned (from calling get_if_info), scan aligned, 
	 * cast ok. */
	rtm = (struct rt_msghdr *)(void *)scan;
	if (rtm->rtm_version != RTM_VERSION) {
	    continue;
	}
	switch (rtm->rtm_type) {
	case RTM_IFINFO:
	    ifm = (struct if_msghdr *)rtm;
	    if (ifm->ifm_addrs & RTA_IFP) {
		struct sockaddr_dl *	dl_p;
		
		dl_p = (struct sockaddr_dl *)(ifm + 1);
		if (dl_p->sdl_nlen == 0 
		    || dl_p->sdl_nlen >= sizeof(ifname)) {
		    goto done;
		}
		bcopy(dl_p->sdl_data, ifname, dl_p->sdl_nlen);
		ifname[dl_p->sdl_nlen] = '\0';
	    }
	    break;
	case RTM_NEWADDR:
	    count++;
	    break;
	default:
	    break;
	}
    }
    if (ifname[0] == '\0') {
	goto done;
    }
    if (count == 0) {
	goto done;
    }
    if (count > INET6_ADDRLIST_N_STATIC) {
	list = (inet6_addrinfo_t *)malloc(sizeof(*list) * count);
	if (list == NULL) {
	    goto done;
	}
    }
    else {
	list = addr_list_p->list_static;
    }
    for (scan = buf; scan < buf_end; scan += rtm->rtm_msglen) {
	boolean_t		got_address = FALSE;
	struct ifa_msghdr *	ifam;
	struct rt_addrinfo	info;

	rtm = (struct rt_msghdr *)(void *)scan;
	if (rtm->rtm_version != RTM_VERSION) {
	    continue;
	}
	if (rtm->rtm_type == RTM_NEWADDR) {
	    ifam = (struct ifa_msghdr *)rtm;
	    info.rti_addrs = ifam->ifam_addrs;
	    error = rt_xaddrs((char *)(ifam + 1),
			      ((char *)ifam) + ifam->ifam_msglen,
			      &info);
	    if (error) {
		fprintf(stderr, "couldn't extract rt_addrinfo %s (%d)\n",
			strerror(error), error);
		goto done;
	    }
	    for (i = 0; i < RTAX_MAX; i++) {
		struct sockaddr_in6 *	sin6_p;
		
		/* ALIGN: info.rti_info aligned (sockaddr), cast ok. */
		sin6_p = (struct sockaddr_in6 *)(void *)info.rti_info[i];
		if (sin6_p == NULL
		    || sin6_p->sin6_len < sizeof(struct sockaddr_in6)) {
		    continue;
		}
		switch (i) {
		case RTAX_NETMASK:
		    list[addr_index].prefix_length 
			= count_prefix_bits(&sin6_p->sin6_addr,
					    sizeof(sin6_p->sin6_addr));
		    break;
		case RTAX_IFA:
		    list[addr_index].addr = sin6_p->sin6_addr;
		    got_address = TRUE;
		    break;
		default:
		    break;
		}
	    }
	    if (got_address) {
		if (s < 0) {
		    s = inet6_dgram_socket();
		}
		if (s >= 0) {
		    siocgifaflag_in6(s, ifname, 
				     &list[addr_index].addr,
				     &list[addr_index].addr_flags);
		    siocgifalifetime_in6(s, ifname, 
					 &list[addr_index].addr,
					 &list[addr_index].valid_lifetime,
					 &list[addr_index].preferred_lifetime);
		}
		/* Mask the v6 LL scope id */
		if (IN6_IS_ADDR_LINKLOCAL(&list[addr_index].addr)) {
		    list[addr_index].addr.s6_addr16[1] = 0;
		    if (linklocal == NULL) {
			linklocal = &list[addr_index];
		    }
		}
		addr_index++;
	    }
	}
    }
    if (addr_index == 0) {
	if (list != addr_list_p->list_static) {
	    free(list);
	}
	list = NULL;
    }

 done:
    if (s >= 0) {
	close(s);
    }
    if (buf != NULL) {
	free(buf);
    }
    addr_list_p->list = list;
    addr_list_p->count = addr_index;
    addr_list_p->linklocal = linklocal;
    return;
}
示例#7
0
// 1419 is the mtu using a 1500 byte ethernet mtu - ipv4 header - udp - dtls with default ciphersuite (I think)
// TODO: read mtu from interface on each OS instead of hard coding 1419 (also have installer set sensible interface MTU)
tuntap::tuntap() : mtu(1419)
{
// TODO: use configuration parameters for registry key names instead of hard coded values
// TODO: package TAP-Windows and change component ID or otherwise figure out how to make it not collide with what OpenVPN uses
	// see comment in %PROGRAMFILES%\TAP-Windows\driver\OemWin2k.inf after installing OpenVPN TAP driver
#ifdef WINDOWS
	sent_sync = true; // no async send in progress
	received_sync = 0;
	memset(&recv_overlapped, 0, sizeof(OVERLAPPED));
	memset(&send_overlapped, 0, sizeof(OVERLAPPED));
	recv_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
	if(recv_event == INVALID_HANDLE_VALUE)
		throw check_err_exception("CreateEvent failed for tuntap recv_event");
	recv_overlapped.hEvent = recv_event;
	// default callback emits error
	read_ready_cb = []() { eout() << "BUG: tuntap read ready callback called but not set"; };
	if(RegisterWaitForSingleObject(&recv_wait, recv_event, &tuntap::read_event_cb, this, INFINITE, WT_EXECUTEINWAITTHREAD) == FALSE)
		throw check_err_exception("RegisterWaitForSingleObject on tuntap read event");
	adapter_GUID = snow::conf[snow::VIRTUAL_INTERFACE];
	if(adapter_GUID == "auto") {
		try {
			// open registry key for all network adapters
			registry_key adapters(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", KEY_READ);
			for(auto &it : adapters.subkeys()) {
				try {
					registry_key adapter = it.get(KEY_READ);
					// TODO: change ComponentId from "tap0901" to some other string to remove possible namespace collision with OpenVPN (this has to occur in the driver too)
					if(adapter.values().get_value_string("ComponentId") == "tap0901") {
						adapter_GUID = adapter.values().get_value_string("NetCfgInstanceId");
						break;
					}
				} catch(const registry_exception &re) {
					dout() << "Failed to access registry subkey: " << re;
				}
				
			}
		} catch (const registry_exception &re) {
			eout() << "FATAL: Failed to open network adapters registry key, cannot determine TUN adapter to use: " << re;
			throw;
		}
	}
	dout() << "Adapter GUID: " << adapter_GUID;
	if(adapter_GUID == "auto")
		throw e_not_found("no usable tuntap interface");
	// [at this point GUID is value of NetCfgInstanceId, although there could be more than one interface: check all against something else? (interface name?)]
	// TODO: probably the thing to do is: on install, create a TAP-Windows interface and set its name to 'snow tunnel interface' or so,
		// then set the GUID in the configuration file [or registry setting], and GUI config program can list interfaces by name and allow user to choose
		// then the configured GUID is the interface we use and all of this mess doesn't even need to go here -- it just goes once on install and in the config editor
		// what would then really be useful would be a way (other than changing the ComponentId) to tell other software (e.g. OpenVPN) not to use a particular interface
			// two possible solutions may be to either make sure that snow starts before the other service [somehow] and gets there first,
			// or setting permissions [somehow] so that only snow process has access
	std::string tap_filename("\\\\.\\Global\\");
	tap_filename += adapter_GUID + ".tap";
	fd = CreateFile(tap_filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0/*no shared access*/, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, nullptr);
	if(fd == INVALID_HANDLE_VALUE)
		throw check_err_exception("Failed to open Windows TUN/TAP device");
	// name of specific instance of adapter as shown in control panel can be found in:
		// "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter_GUID + "\\Connection"
		// value is "Name"
	
	// set to TUN mode
	// TAP_WIN_IOCTL_CONFIG_TUN takes three args: interface IP addr, network addr and netmask
	if_info ifinfo = get_if_info();
	uint32_t tun_addrs[3] = { ifinfo.if_addr, ifinfo.if_addr & ifinfo.netmask, ifinfo.netmask };
	DWORD rsize;
	if(DeviceIoControl(fd, TAP_WINDOWS_IOCTL_CONFIG_TUN, tun_addrs, sizeof(tun_addrs), tun_addrs, sizeof(tun_addrs), &rsize, nullptr))
		dout() << "TAP-Windows CONFIG_TUN success: " << ss_ipaddr(tun_addrs[0]) << " " << ss_ipaddr(tun_addrs[1]) << " " << ss_ipaddr(tun_addrs[2]);
	else
		eout() << "TAP-Windows CONFIG_TUN FAIL: " << ss_ipaddr(tun_addrs[0]) << " " << ss_ipaddr(tun_addrs[1]) << " " << ss_ipaddr(tun_addrs[2]);

	// set media status as connected
	ULONG connected = TRUE;
	if(DeviceIoControl(fd, TAP_WINDOWS_IOCTL_SET_MEDIA_STATUS, &connected, sizeof(connected), &connected, sizeof(connected), &rsize, nullptr) == FALSE)
		wout() << "Failed to set TAP-Windows media status to connected";
	ULONG ifmtu;
	if(DeviceIoControl(fd, TAP_WINDOWS_IOCTL_GET_MTU, &ifmtu, sizeof(ifmtu), &ifmtu, sizeof(ifmtu), &rsize, nullptr)) {
		dout() << "Read mtu from TAP-Windows interface: " << ifmtu;
		if(ifmtu > MIN_PMTU)
			mtu = ifmtu;
	} else {
		wout() << "Failed to get Tap-Windows MTU, assuming default";
	}
	
	// [flush ARP cache? -> probably unnecessary with tun, but maybe do it anyway? certainly don't want invalid ARP cache entries for pool addrs from before interface startup]
	
	// ... also (may) need to undo whatever configuration (remove addrs from if, routes, etc.) on destruction, CloseHandle on fd, set media status to disconnected, etc.

#else
	check_err((fd = open(snow::conf[snow::CLONE_DEVICE].c_str(), O_RDWR)), "opening tun/tap clone device");
	ifreq ifr;
	memset(&ifr, 0, sizeof(ifr));
	// check size manually instead of using strncpy: strncpy fails silently and doesn't null terminate if there is insufficient space
	if(snow::conf[snow::VIRTUAL_INTERFACE].size() >= IFNAMSIZ)
		throw check_err_exception("VIRTUAL_INTERFACE name is too long", false);
	strcpy(ifr.ifr_name, snow::conf[snow::VIRTUAL_INTERFACE].c_str());
	check_err(fcntl(fd, F_SETFL, O_NONBLOCK), "setting tuntap socket to non-blocking");
#ifdef __linux__
	ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
	check_err(ioctl(fd, TUNSETIFF, (void*) &ifr), "opening tun/tap interface");
#endif
	// note: Mac and BSD require a stupid hack to make tun behave properly because they insist on a single destination address being specified
		// solution is to exclude an address from the address pool and specify it as the destination when configuring the interface
		// then set a route specifying that address as the gateway for the entire snow subnet so OS will send them all to the tun interface
	// TODO: write code to do that programmatically for Mac/BSD
		// existing code seems to work on BSD if you set CLONE_DEVICE to e.g. /dev/tun0 and VIRTUAL_INTERFACE to e.g. tun0 and configure the tun interface manually, e.g.:
		// # ifconfig tun0 create 172.16.0.1 netmask 255.240.0.0 172.31.255.254 mtu 1419
		// # route add -net 172.16.0.0 172.31.255.254 255.240.0.0
		// (note: this must be done each time you start the daemon, when the daemon exits the interface remains but configuration is forgotten; same two commands w/o "create")
		// (note: 'ifconfig tun create' will create next tun# necessary, see if there is any simple way to replicate with API)
		// doing this programmatically requires call to ioctl passing SIOCSIFPHYADDR with in_aliasreq struct as follows:
			// ifra_name = "tun[#]"
			// ifra_addr as local interface addr
			// ifra_dstaddr as fake addr
			// ifra_mask as subnet mask
		// and then adding the route via some call to the BSD routing API
	csocket sock(AF_INET, SOCK_DGRAM); // need ordinary socket for SIOC[GS]*, can't use tun fd
	check_err(ioctl(sock.fd(), SIOCGIFFLAGS, (void*) &ifr), "getting tuntap interface flags");
	if((ifr.ifr_flags & IFF_UP) == 0) {
		dout() << "tuntap interface was not up, trying to bring it up";
		ifr.ifr_flags |= IFF_UP; // make sure interface is up
		check_err(ioctl(sock.fd(), SIOCSIFFLAGS, (void*) &ifr), "setting tuntap interface flags");
	} else {
		dout() << "tuntap interface was up";
	}
	// there are two possible ways of doing this which are both supported: either snow launches as root or with CAP_NET_ADMIN and sets these here,
		// or the interface is persistent and configured ahead of time, in which case only ownership of the interface is necessary
	// so what we do is check that everything is configured correctly and try to fix it if it isn't
	// that way everything is fine as long as the interface is correctly preconfigured -or- it isn't but we have rights to fix it
	in_addr addr, netmask;
	inet_pton(AF_INET, snow::conf[snow::NATPOOL_NETWORK].c_str(), &addr.s_addr);
	addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
	netmask.s_addr = ~htonl((1 << (32 - snow::conf[snow::NATPOOL_NETMASK_BITS])) - 1);
	ifr.ifr_addr.sa_family = AF_INET;
	// EADDRNOTAVAIL is returned if no address is assigned which just means we have to assign the address, so then ifr_addr will be zero and not match addr
	int rv = ioctl(sock.fd(), SIOCGIFADDR, &ifr);
	if(rv < 0 && errno != EADDRNOTAVAIL)
		throw check_err_exception("getting tun/tap interface IP address");
	sockaddrunion su;
	su.s = ifr.ifr_addr;
	dout() << "Got tuntap ifaddr " << ss_ipaddr(su.sa.sin_addr.s_addr);
	if(su.sa.sin_addr.s_addr != addr.s_addr) {
		dout() << "Virtual interface IP addr was " << ss_ipaddr(su.sa.sin_addr.s_addr) << ", should be " << ss_ipaddr(addr.s_addr) << ", trying to fix";
		su.sa.sin_addr = addr;
		ifr.ifr_addr = su.s;
		check_err(ioctl(sock.fd(), SIOCSIFADDR, &ifr), "setting tun/tap interface IP address");
	}
	check_err(ioctl(sock.fd(), SIOCGIFNETMASK, &ifr), "getting tun/tap interface netmask");
	su.s = ifr.ifr_addr;
	dout() << "Got tuntap netmask " << ss_ipaddr(su.sa.sin_addr.s_addr);
	if(su.sa.sin_addr.s_addr != netmask.s_addr) {
		dout() << "Virtual interface netmask was " << ss_ipaddr(su.sa.sin_addr.s_addr) << ", should be " << ss_ipaddr(netmask.s_addr) << ", trying to fix";
		su.sa.sin_addr = netmask;
		ifr.ifr_addr = su.s;
		check_err(ioctl(sock.fd(),  SIOCSIFNETMASK, &ifr), "setting tun/tap interface netmask");
	}
	mtu = snow::conf[snow::VIRTUAL_INTERFACE_MTU];
	check_err(ioctl(sock.fd(), SIOCGIFMTU, (void*) &ifr), "getting tun/tap interface MTU");
	dout() << "Existing tuntap interface MTU: " << ifr.ifr_mtu;
	if(ifr.ifr_mtu <  MIN_PMTU || mtu != static_cast<unsigned>(ifr.ifr_mtu)) {
		dout() << "Virtual interface mtu was " << ifr.ifr_mtu << ", should be " << mtu << ", trying to fix";
		ifr.ifr_mtu = mtu;
		check_err(ioctl(sock.fd(), SIOCSIFMTU, (void*) &ifr), "setting tun/tap interface MTU");
	}
	iout() << "Virtual interface configured with network " << ss_ipaddr(addr.s_addr&netmask.s_addr) << " netmask " << ss_ipaddr(netmask.s_addr) <<  " address " << ss_ipaddr(addr.s_addr) << " MTU " << mtu;	
#endif
}
示例#8
0
void host_init(char *ifname) {
  static struct local_host_info host_info;
  struct sockaddr_in *ina;
  char buf[1024];
  struct ifconf ifc;
  struct ifreq *ifr;
  int i, iw_sock;

  /* Make sure the global "this_host" pointer points to the info
     structure so that the information can be accessed from
     outside this function... */
  memset(&host_info, '\0', sizeof(struct local_host_info));
  this_host = &host_info;
  
  /* Find the first wireless interface */
  if(ifname != NULL) 
    strcpy(host_info.ifname, ifname);
  else {
    iw_sock= socket(AF_INET, SOCK_DGRAM, 0);
    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    if(ioctl(iw_sock, SIOCGIFCONF, &ifc) < 0) {
      fprintf(stderr, "Could not get wireless info\n");
      exit(-1);
    }
    ifr = ifc.ifc_req;
    for(i = ifc.ifc_len / sizeof(struct ifreq); i >= 0; i--, ifr++) {
      struct iwreq req;
	strcpy(req.ifr_name, ifr->ifr_name);
	if (ioctl(iw_sock, SIOCGIWNAME, &req) >= 0) {
	  strcpy(host_info.ifname, ifr->ifr_name);
	  break;
	}
    }
    close(iw_sock);
    
    /* Did we find a wireless interface? */
    if(host_info.ifname[0] == '\0') {
      fprintf(stderr, "Could not find a wireless interface!\n");
      fprintf(stderr, "Use -i <interface> to override...\n");
      exit(-1);
    }
  }
  
  /* Load required kernel modules */
  load_modules(host_info.ifname);
  
  /* Get IP-address of interface... */
  ina = get_if_info(host_info.ifname, SIOCGIFADDR);
  if(ina == NULL)
    exit(-1);
  
  /* Remember our host IP address... */
  host_info.ipaddr = ntohl(ina->sin_addr.s_addr);

  /* printf("Address of interface %s is %s\n", host_info.ifname,  */
  /* 	 ip_to_str(host_info.ipaddr)); */

  /* Get netmask of interface... */
  ina = get_if_info(host_info.ifname, SIOCGIFNETMASK);
  if(ina == NULL)
    exit(-1);
  
  /* Remember the netmask */
  host_info.netmask = ntohl(ina->sin_addr.s_addr);

  /* printf("Netmask of interface %s is %s\n", host_info.ifname,  */
  /* 	 ip_to_str(host_info.netmask)); */
  
  ina = get_if_info(host_info.ifname, SIOCGIFBRDADDR);
  if(ina == NULL)
    exit(-1);

  host_info.broadcast = ntohl(ina->sin_addr.s_addr);
  /* printf("Broadcast address is %s\n", ip_to_str(host_info.broadcast)); */

  /* Enable IP forwarding and set other kernel options... */
  if(set_kernel_options(host_info.ifname) < 0) {
    fprintf(stderr, "Could not set kernel options!\n");
    exit(-1);
  }
 
  /* Add broadcast route (255.255.255.255) */
  k_add_rte(AODV_BROADCAST, 0, 0, 0); 
  
  /* Intitialize the local sequence number an flood_id to zero */
  host_info.seqno = 0;
  host_info.flood_id = 0;
 
}
示例#9
0
文件: dladm.c 项目: andreiw/polaris
static void
do_show_dev(int argc, char *argv[])
{
	int		option;
	char		*dev = NULL;
	boolean_t	s_arg = B_FALSE;
	boolean_t	i_arg = B_FALSE;
	uint32_t	interval = 0;
	show_mac_state_t state;
	char		*endp = NULL;

	state.ms_parseable = B_FALSE;

	opterr = 0;
	while ((option = getopt_long(argc, argv, ":psi:",
	    longopts, NULL)) != -1) {
		switch (option) {
		case 'p':
			state.ms_parseable = B_TRUE;
			break;
		case 's':
			if (s_arg) {
				(void) fprintf(stderr, gettext(
				    "%s: the option -s cannot be specified "
				    "more than once\n"), progname);
				usage();
			}

			s_arg = B_TRUE;
			break;
		case 'i':
			if (i_arg) {
				(void) fprintf(stderr, gettext(
				    "%s: the option -i cannot be specified "
				    "more than once\n"), progname);
				usage();
			}

			i_arg = B_TRUE;

			errno = 0;
			interval = (int)strtol(optarg, &endp, 10);
			if (errno != 0 || interval == 0 || *endp != '\0') {
				(void) fprintf(stderr,
				    gettext("%s: invalid interval value"
				    " '%d'\n"),
				    progname, interval);
				exit(1);
			}
			break;
		case ':':
			(void) fprintf(stderr,
			    gettext("%s: option requires a value '-%c'\n"),
			    progname, optopt);
			exit(1);
			/*NOTREACHED*/
		case '?':
		default:
			(void) fprintf(stderr,
			    gettext("%s: unrecognized option '-%c'\n"),
			    progname, optopt);
			exit(1);
		}
	}

	if (i_arg && !s_arg) {
		(void) fprintf(stderr, gettext("%s: the option -i "
		    "can be used only with -s\n"), progname);
		usage();
	}

	/* get dev name (optional last argument) */
	if (optind == (argc-1))
		dev = argv[optind];
	else if (optind != argc)
		usage();

	if (dev != NULL) {
		int		index;
		char		drv[LIFNAMSIZ];
		dladm_attr_t	dlattr;
		boolean_t	legacy;

		/*
		 * Check for invalid devices.
		 * aggregations and vlans are not considered devices.
		 */
		if (strncmp(dev, "aggr", 4) == 0 ||
		    dlpi_if_parse(dev, drv, &index) < 0 ||
		    index >= 1000 ||
		    get_if_info(dev, &dlattr, &legacy) < 0) {
			(void) fprintf(stderr,
			    gettext("%s: invalid device '%s'\n"),
			    progname, dev);
			exit(1);
		}
	}

	if (s_arg) {
		dev_stats(dev, interval);
		return;
	}

	if (dev == NULL)
		(void) macadm_walk(show_dev, &state, B_TRUE);
	else
		show_dev(&state, dev);
}
示例#10
0
/*
 * check_ip
 *  check if our ip own by other host 
 *  though sending arp package
 *
 * Input
 *  interface	- interface used to send pkg
 *  dst_ip	- IP addr which will be check
 *
 * Return Value
 *  0		- if IP addr not been used
 *  1		- if IP addr has been used
 *  -1		- error
 */
int check_ip(char *interface/*, in_addr_t dst_ip*/)
{
	int		exist = 0;	/* is it dst_ip already exist? */
	int		fd;
	int		optval =  1;
	unsigned char	s_macaddr[6];	/* our MAC addr */
	in_addr_t	s_ipaddr;	/* our IP addr */
	arp_pkg_t	arp_req;
	struct sockaddr	sa;

	fd_set		read_fds;	
	struct timeval	tm;
	time_t		prev_time;
	int		timeout = MAX_TIMEOUT;

	/* acquire own addr */
	if ( get_if_info(interface, s_macaddr, &s_ipaddr) != 0 ) {
		fprintf(stderr, "Couldn't acquire MAC & IP addr\n");
		return -1;
	}

	/* open socket */
	fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
	if ( fd < 0 )			/* open socket failed */
		return -1;
	if ( setsockopt(fd, SOL_SOCKET, 
			SO_BROADCAST, 
			&optval, 
			sizeof(optval)) < 0 )
		return -1;

	/* fill the packet header */
	memset(&arp_req, 0, sizeof(arp_pkg_t));
	memcpy(arp_req.ethhdr.h_dest, MAC_BROADCAST_ADDR, 6);
	memcpy(arp_req.ethhdr.h_source, s_macaddr, 6);
	arp_req.ethhdr.h_proto	= htons(ETH_P_ARP);		/* protocol type */
	arp_req.htype	= htons(ARPHRD_ETHER);			/* hardware type */
	arp_req.ptype	= htons(ETH_P_IP);				/* protocol type (ARP message) */
	arp_req.hlen	= 6;							/* hardware addr length */
	arp_req.plen	= 4;							/* protocol address length */
	arp_req.operation = htons(ARPOP_REQUEST);		/* ARP op code */
	memcpy(arp_req.sHaddr, s_macaddr, 6);			/* source MAC addr */
	memcpy(arp_req.tInaddr, &s_ipaddr, 4);
	*(in_addr_t *)arp_req.sInaddr = 0;				/* set to 0 for IP conflict dect */
	//*(in_addr_t *)arp_req.sInaddr = s_ipaddr;		/* source IP addr */
	//*(in_addr_t *)arp_req.tInaddr = s_ipaddr;		/* target IP addr */

	/* send the request */
	memset(&sa, 0, sizeof(sa));
	strcpy(sa.sa_data, interface);
	if ( sendto(fd, &arp_req, sizeof(arp_req), 0, &sa, sizeof(sa)) < 0 ) {
		fprintf(stderr, "NETWORK: send arp request failed\n");
		return -1;
	}

	/* wait for reply */
	tm.tv_usec = 0;
	time(&prev_time);			/* get current time */
	while (timeout > 0) {
		tm.tv_sec = timeout;

		/* wait for sock ready */
		FD_ZERO(&read_fds);
		FD_SET(fd, &read_fds);
		if ( select( fd+1, &read_fds, NULL, NULL, &tm) < 0 ) {
			fprintf(stderr, "NETWORK: error occur while wait for reply\n");
			return -1;
		}

		/* receive reply */
		if ( recv(fd, &arp_req, sizeof(arp_req), 0)  < 0 ) {
			fprintf(stderr, "NETWORK: recv arp request failed\n");
			return -1;
		}

		/* check if the right reply we expected */
		if ( arp_req.operation == htons(ARPOP_REPLY) &&		/* it's a arp reply */
			bcmp(arp_req.tHaddr, s_macaddr, 6) == 0 &&	/* and it's to us */
			/* TODO I think we should check if the sender's mac addr 
			   different from us */
			*((in_addr_t*)arp_req.sInaddr) == s_ipaddr) {	/* and it's from right place */
			exist = 1;
			break;
		}
		
		timeout = timeout - (time(NULL) - prev_time);
		time(&prev_time);
	}

	close(fd);

	return exist;
}
示例#11
0
int mcast::mcast_grp::init(const char* addr,const char* iface,int ttl,int loop)
{
    if(!iface)
        iface="";

    mcast_ttl=ttl;
    mcast_loop=loop;

    mcast_sin.sin_family=AF_INET;
    mcast_sin.sin_port=0;
    mcast_sin.sin_addr.s_addr=INADDR_ANY;
#ifdef __FreeBSD__
    mcast_sin.sin_len=sizeof(mcast_sin);
#endif /* __FreeBSD__ */

    mcast_if_sin.sin_family=AF_INET;
    mcast_if_sin.sin_port=0;
    mcast_if_sin.sin_addr.s_addr=INADDR_ANY;
#ifdef __FreeBSD__
    mcast_if_sin.sin_len=sizeof(mcast_if_sin);
#endif /* __FreeBSD__ */

    *interface=0;

    char tmp[256];
    strcpy(tmp,addr);

    if(mcast_ttl<1)
        mcast_ttl=1;

    char* port=strchr(tmp,':');
    if(port)
    {
        *port=0;
        mcast_sin.sin_port=htons(atoi(port+1));
    }

    mcast_sin.sin_addr.s_addr=inet_addr(tmp);

    int if_by_name=0;
    for(const char* p=iface;*p;p++)
        if(isalpha(*p))
            { if_by_name=1; break; }

    if(*iface)
    {
        if(if_by_name)
        {
            if(verb_fp)
                fprintf(verb_fp,"find multicast interface address by name '%s'\n",iface);

            if_info ifi;
            get_if_info(iface,&ifi);
            memcpy((char*)&mcast_if_sin,&ifi.if_sin,sizeof(sockaddr_in));
        }else
            mcast_if_sin.sin_addr.s_addr=inet_addr(iface);
    }

    if(mcast_if_sin.sin_addr.s_addr==INADDR_ANY)
    {
        if(verb_fp)
            fprintf(verb_fp,"find multicast default interface address\n");
        mcast_if_sin.sin_addr=get_best_mcast_if_addr();
    }

    if(verb_fp)
    {
        fprintf(verb_fp,"multicast interface address: '%s'\n",mcast_if_sin.sin_addr.s_addr==INADDR_ANY?"any":inet_ntoa(mcast_if_sin.sin_addr));
        fprintf(verb_fp,"multicast group address: '%s:%i'\n",inet_ntoa(mcast_sin.sin_addr),ntohs(mcast_sin.sin_port));
    }

    snprintf(interface,sizeof(interface),"%s",inet_ntoa(mcast_if_sin.sin_addr));

    return 0;
}