Beispiel #1
0
static errno_t
utun_ctl_connect(
	kern_ctl_ref		kctlref,
	struct sockaddr_ctl	*sac, 
	void				**unitinfo)
{
	struct ifnet_init_eparams	utun_init;
	struct utun_pcb				*pcb;
	errno_t						result;
	struct ifnet_stats_param 	stats;
	
	/* kernel control allocates, interface frees */
	pcb = utun_alloc(sizeof(*pcb));
	if (pcb == NULL)
		return ENOMEM;
	
	/* Setup the protocol control block */
	bzero(pcb, sizeof(*pcb));
	*unitinfo = pcb;
	pcb->utun_ctlref = kctlref;
	pcb->utun_unit = sac->sc_unit;
	
	printf("utun_ctl_connect: creating interface utun%d\n", pcb->utun_unit - 1);

	/* Create the interface */
	bzero(&utun_init, sizeof(utun_init));
	utun_init.ver = IFNET_INIT_CURRENT_VERSION;
	utun_init.len = sizeof (utun_init);
	utun_init.flags = IFNET_INIT_LEGACY;
	utun_init.name = "utun";
	utun_init.unit = pcb->utun_unit - 1;
	utun_init.family = utun_family;
	utun_init.type = IFT_OTHER;
	utun_init.output = utun_output;
	utun_init.demux = utun_demux;
	utun_init.framer_extended = utun_framer;
	utun_init.add_proto = utun_add_proto;
	utun_init.del_proto = utun_del_proto;
	utun_init.softc = pcb;
	utun_init.ioctl = utun_ioctl;
	utun_init.detach = utun_detached;
	
	result = ifnet_allocate_extended(&utun_init, &pcb->utun_ifp);
	if (result != 0) {
		printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result);
		utun_free(pcb);
		return result;
	}
	OSIncrementAtomic(&utun_ifcount);
	
	/* Set flags and additional information. */
	ifnet_set_mtu(pcb->utun_ifp, 1500);
	ifnet_set_flags(pcb->utun_ifp, IFF_UP | IFF_MULTICAST | IFF_POINTOPOINT, 0xffff);

	/* The interface must generate its own IPv6 LinkLocal address,
	 * if possible following the recommendation of RFC2472 to the 64bit interface ID
	 */
	ifnet_set_eflags(pcb->utun_ifp, IFEF_NOAUTOIPV6LL, IFEF_NOAUTOIPV6LL);
	
	/* Reset the stats in case as the interface may have been recycled */
	bzero(&stats, sizeof(struct ifnet_stats_param));
	ifnet_set_stat(pcb->utun_ifp, &stats);

	/* Attach the interface */
	result = ifnet_attach(pcb->utun_ifp, NULL);
	if (result != 0) {
		printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result);
		ifnet_release(pcb->utun_ifp);
		utun_free(pcb);
	}
	
	/* Attach to bpf */
	if (result == 0)
		bpfattach(pcb->utun_ifp, DLT_NULL, 4);
	
	/* The interfaces resoures allocated, mark it as running */
	if (result == 0)
		ifnet_set_flags(pcb->utun_ifp, IFF_RUNNING, IFF_RUNNING);
	
	return result;
}
Beispiel #2
0
static errno_t
utun_ctl_connect(
	kern_ctl_ref		kctlref,
	struct sockaddr_ctl	*sac, 
	void				**unitinfo)
{
	struct ifnet_init_eparams	utun_init;
	struct utun_pcb				*pcb;
	errno_t						result;
	struct ifnet_stats_param 	stats;
	
	/* kernel control allocates, interface frees */
	MALLOC(pcb, struct utun_pcb *, sizeof(*pcb), M_DEVBUF, M_WAITOK | M_ZERO);

	*unitinfo = pcb;
	pcb->utun_ctlref = kctlref;
	pcb->utun_unit = sac->sc_unit;
	pcb->utun_max_pending_packets = 1;
	
	printf("utun_ctl_connect: creating interface utun%d\n", pcb->utun_unit - 1);

	/* Create the interface */
	bzero(&utun_init, sizeof(utun_init));
	utun_init.ver = IFNET_INIT_CURRENT_VERSION;
	utun_init.len = sizeof (utun_init);
	utun_init.name = "utun";
	utun_init.start = utun_start;
	utun_init.unit = pcb->utun_unit - 1;
	utun_init.family = utun_family;
	utun_init.subfamily = IFNET_SUBFAMILY_UTUN;
	utun_init.type = IFT_OTHER;
	utun_init.demux = utun_demux;
	utun_init.framer_extended = utun_framer;
	utun_init.add_proto = utun_add_proto;
	utun_init.del_proto = utun_del_proto;
	utun_init.softc = pcb;
	utun_init.ioctl = utun_ioctl;
	utun_init.detach = utun_detached;

	/*
	 * Upon success, this holds an ifnet reference which we will
	 * release via ifnet_release() at final detach time.
	 */
	result = ifnet_allocate_extended(&utun_init, &pcb->utun_ifp);
	if (result != 0) {
		printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result);
		*unitinfo = NULL;
		FREE(pcb, M_DEVBUF);
		return result;
	}
	
	/* Set flags and additional information. */
	ifnet_set_mtu(pcb->utun_ifp, UTUN_DEFAULT_MTU);
	ifnet_set_flags(pcb->utun_ifp, IFF_UP | IFF_MULTICAST | IFF_POINTOPOINT, 0xffff);

	/* The interface must generate its own IPv6 LinkLocal address,
	 * if possible following the recommendation of RFC2472 to the 64bit interface ID
	 */
	ifnet_set_eflags(pcb->utun_ifp, IFEF_NOAUTOIPV6LL, IFEF_NOAUTOIPV6LL);
	
	/* Reset the stats in case as the interface may have been recycled */
	bzero(&stats, sizeof(struct ifnet_stats_param));
	ifnet_set_stat(pcb->utun_ifp, &stats);

	/* Attach the interface */
	result = ifnet_attach(pcb->utun_ifp, NULL);
	if (result != 0) {
		printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result);
		/* Release reference now since attach failed */
		ifnet_release(pcb->utun_ifp);
		*unitinfo = NULL;
		FREE(pcb, M_DEVBUF);
	} else {
		/* Attach to bpf */
		bpfattach(pcb->utun_ifp, DLT_NULL, UTUN_HEADER_SIZE(pcb));
		/* The interfaces resoures allocated, mark it as running */
		ifnet_set_flags(pcb->utun_ifp, IFF_RUNNING, IFF_RUNNING);
	}
	return result;
}