1/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */ 2 3/* 4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 5 * Nottingham University 1987. 6 * 7 * This source may be freely distributed, however I would be interested 8 * in any changes that are made. 9 * 10 * This driver takes packets off the IP i/f and hands them up to a 11 * user process to have its wicked way with. This driver has it's 12 * roots in a similar driver written by Phil Cockcroft (formerly) at 13 * UCL. This driver is based much more on read/write/poll mode of 14 * operation though. 15 * |
16 * $FreeBSD: head/sys/net/if_tun.c 111742 2003-03-02 15:56:49Z des $ |
17 */ 18 19#include "opt_inet.h" 20#include "opt_mac.h" 21 22#include <sys/param.h> 23#include <sys/proc.h> 24#include <sys/systm.h> --- 105 unchanged lines hidden (view full) --- 130 tunbasedev = (*dev)->si_udev; 131 else { 132 (*dev)->si_flags |= SI_CHEAPCLONE; 133 dev_depends(udev2dev(tunbasedev, 0), *dev); 134 } 135} 136 137static int |
138tunmodevent(module_t mod, int type, void *data) |
139{ 140 static eventhandler_tag tag; 141 struct tun_softc *tp; 142 dev_t dev; 143 int err; 144 |
145 switch (type) { 146 case MOD_LOAD: |
147 tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000); 148 if (tag == NULL) 149 return (ENOMEM); 150 tununits.rm_type = RMAN_ARRAY; 151 tununits.rm_descr = "open if_tun units"; 152 err = rman_init(&tununits); 153 if (err != 0) { 154 EVENTHANDLER_DEREGISTER(dev_clone, tag); 155 return (err); 156 } 157 err = rman_manage_region(&tununits, 0, TUN_MAXUNIT); 158 if (err != 0) { 159 printf("%s: tununits: rman_manage_region: Failed %d\n", 160 TUNNAME, err); 161 rman_fini(&tununits); 162 EVENTHANDLER_DEREGISTER(dev_clone, tag); 163 return (err); 164 } |
165 break; 166 case MOD_UNLOAD: |
167 err = rman_fini(&tununits); 168 if (err != 0) 169 return (err); 170 EVENTHANDLER_DEREGISTER(dev_clone, tag); 171 172 while (tunhead != NULL) { 173 KASSERT((tunhead->tun_flags & TUN_OPEN) == 0, 174 ("tununits is out of sync - unit %d", --- 12 unchanged lines hidden (view full) --- 187 /* 188 * Destroying tunbasedev results in all of our make_dev()s 189 * conveniently going away. 190 */ 191 if (tunbasedev != NOUDEV) 192 destroy_dev(udev2dev(tunbasedev, 0)); 193 194 break; |
195 } 196 return 0; 197} |
198 |
199static moduledata_t tun_mod = { 200 "if_tun", 201 tunmodevent, |
202 0 |
203}; |
204 205DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 206 207static void 208tunstart(struct ifnet *ifp) 209{ 210 struct tun_softc *tp = ifp->if_softc; 211 --- 97 unchanged lines hidden (view full) --- 309 310 if (ifp->if_flags & IFF_UP) { 311 s = splimp(); 312 if_down(ifp); 313 splx(s); 314 } 315 316 if (ifp->if_flags & IFF_RUNNING) { |
317 struct ifaddr *ifa; |
318 319 s = splimp(); 320 /* find internet addresses and delete routes */ 321 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) 322 if (ifa->ifa_addr->sa_family == AF_INET) 323 rtinit(ifa, (int)RTM_DELETE, 324 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 325 ifp->if_flags &= ~IFF_RUNNING; --- 9 unchanged lines hidden (view full) --- 335 336 return (0); 337} 338 339static int 340tuninit(struct ifnet *ifp) 341{ 342 struct tun_softc *tp = ifp->if_softc; |
343 struct ifaddr *ifa; |
344 int error = 0; 345 346 TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 347 348 ifp->if_flags |= IFF_UP | IFF_RUNNING; 349 getmicrotime(&ifp->if_lastchange); 350 |
351 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; |
352 ifa = TAILQ_NEXT(ifa, ifa_link)) { 353 if (ifa->ifa_addr == NULL) 354 error = EFAULT; 355 /* XXX: Should maybe return straight off? */ 356 else { 357#ifdef INET 358 if (ifa->ifa_addr->sa_family == AF_INET) { 359 struct sockaddr_in *si; --- 167 unchanged lines hidden (view full) --- 527 * the cdevsw interface is now pretty minimal. 528 */ 529static int 530tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) 531{ 532 int s; 533 int error; 534 struct tun_softc *tp = dev->si_drv1; |
535 struct tuninfo *tunp; |
536 537 switch (cmd) { |
538 case TUNSIFINFO: 539 tunp = (struct tuninfo *)data; |
540 if (tunp->mtu < IF_MINMTU) 541 return (EINVAL); |
542 if (tp->tun_if.if_mtu != tunp->mtu |
543 && (error = suser(td)) != 0) 544 return (error); |
545 tp->tun_if.if_mtu = tunp->mtu; 546 tp->tun_if.if_type = tunp->type; 547 tp->tun_if.if_baudrate = tunp->baudrate; 548 break; 549 case TUNGIFINFO: 550 tunp = (struct tuninfo *)data; 551 tunp->mtu = tp->tun_if.if_mtu; 552 tunp->type = tp->tun_if.if_type; 553 tunp->baudrate = tp->tun_if.if_baudrate; 554 break; |
555 case TUNSDEBUG: 556 tundebug = *(int *)data; 557 break; 558 case TUNGDEBUG: 559 *(int *)data = tundebug; 560 break; 561 case TUNSLMODE: 562 if (*(int *)data) { 563 tp->tun_flags |= TUN_LMODE; 564 tp->tun_flags &= ~TUN_IFHEAD; 565 } else 566 tp->tun_flags &= ~TUN_LMODE; 567 break; 568 case TUNSIFHEAD: 569 if (*(int *)data) { 570 tp->tun_flags |= TUN_IFHEAD; 571 tp->tun_flags &= ~TUN_LMODE; |
572 } else |
573 tp->tun_flags &= ~TUN_IFHEAD; 574 break; 575 case TUNGIFHEAD: 576 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0; 577 break; 578 case TUNSIFMODE: 579 /* deny this if UP */ 580 if (tp->tun_if.if_flags & IFF_UP) --- 20 unchanged lines hidden (view full) --- 601 tp->tun_flags |= TUN_ASYNC; 602 else 603 tp->tun_flags &= ~TUN_ASYNC; 604 break; 605 case FIONREAD: 606 s = splimp(); 607 if (tp->tun_if.if_snd.ifq_head) { 608 struct mbuf *mb = tp->tun_if.if_snd.ifq_head; |
609 for( *(int *)data = 0; mb != 0; mb = mb->m_next) |
610 *(int *)data += mb->m_len; 611 } else 612 *(int *)data = 0; 613 splx(s); 614 break; 615 case FIOSETOWN: 616 return (fsetown(*(int *)data, &tp->tun_sigio)); 617 --- 216 unchanged lines hidden --- |