- struct tun *st;
- item_t *item;
- dict_t *dict;
- struct ifreq ifr;
-
- st=safe_malloc(sizeof(*st),"tun_apply");
-
- /* First parameter must be a dict */
- item=list_elem(args,0);
- if (!item || item->type!=t_dict)
- cfgfatal(loc,"tun","parameter must be a dictionary\n");
-
- dict=item->data.dict;
-
- st->netlink_to_tunnel=
- netlink_init(&st->nl,st,loc,dict,
- "netlink-tun",tun_deliver_to_kernel);
-
- st->device_path=dict_read_string(dict,"device",False,"tun-netlink",loc);
- st->interface_name=dict_read_string(dict,"interface",False,
- "tun-netlink",loc);
- st->ifconfig_path=dict_read_string(dict,"ifconfig-path",
- False,"tun-netlink",loc);
- st->route_path=dict_read_string(dict,"route-path",
- False,"tun-netlink",loc);
-
- if (!st->device_path) st->device_path="/dev/net/tun";
- if (!st->ifconfig_path) st->ifconfig_path="ifconfig";
- if (!st->route_path) st->route_path="route";
- st->buff=find_cl_if(dict,"buffer",CL_BUFFER,True,"tun-netlink",loc);
-
- /* New TUN interface: open the device, then do ioctl TUNSETIFF
- to set or find out the network interface name. */
- st->fd=open(st->device_path,O_RDWR);
- if (st->fd==-1) {
- fatal_perror("%s: can't open device file %s",st->nl.name,
- st->device_path);
- }
- memset(&ifr,0,sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Just send/receive IP packets,
- no extra headers */
- if (st->interface_name)
- strncpy(ifr.ifr_name,st->interface_name,IFNAMSIZ);
- if (ioctl(st->fd,TUNSETIFF,&ifr)<0) {
- fatal_perror("%s: ioctl(TUNSETIFF)",st->nl.name);
- }
- if (!st->interface_name) {
- st->interface_name=safe_malloc(strlen(ifr.ifr_name)+1,"tun_apply");
- strcpy(st->interface_name,ifr.ifr_name);
- Message(M_INFO,"%s: allocated network interface %s\n",st->nl.name,
- st->interface_name);
- }
-
- add_hook(PHASE_DROPPRIV,tun_phase_hook,st);
-
- return new_closure(&st->nl.cl);