if_tun.c revision 121816
153812Salfred/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */ 2281981Skib 353812Salfred/* 453812Salfred * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 553812Salfred * Nottingham University 1987. 653812Salfred * 753812Salfred * This source may be freely distributed, however I would be interested 853812Salfred * in any changes that are made. 953812Salfred * 1059501Sphantom * This driver takes packets off the IP i/f and hands them up to a 11124535Sru * user process to have its wicked way with. This driver has it's 1253812Salfred * roots in a similar driver written by Phil Cockcroft (formerly) at 1384306Sru * UCL. This driver is based much more on read/write/poll mode of 1453812Salfred * operation though. 1553812Salfred * 1653812Salfred * $FreeBSD: head/sys/net/if_tun.c 121816 2003-10-31 18:32:15Z brooks $ 1753812Salfred */ 1853812Salfred 1953812Salfred#include "opt_atalk.h" 2053812Salfred#include "opt_inet.h" 2153812Salfred#include "opt_inet6.h" 2253812Salfred#include "opt_ipx.h" 2353812Salfred#include "opt_mac.h" 2453812Salfred 2553812Salfred#include <sys/param.h> 2686074Smurray#include <sys/proc.h> 2786074Smurray#include <sys/systm.h> 2886074Smurray#include <sys/mac.h> 2986074Smurray#include <sys/mbuf.h> 3086074Smurray#include <sys/module.h> 3153812Salfred#include <sys/socket.h> 3253812Salfred#include <sys/filio.h> 3353812Salfred#include <sys/sockio.h> 3453812Salfred#include <sys/ttycom.h> 3553812Salfred#include <sys/poll.h> 3653812Salfred#include <sys/signalvar.h> 3753812Salfred#include <sys/filedesc.h> 3853812Salfred#include <sys/kernel.h> 3953812Salfred#include <sys/sysctl.h> 4053812Salfred#include <sys/conf.h> 4153812Salfred#include <sys/uio.h> 4253812Salfred#include <sys/vnode.h> 4353812Salfred#include <sys/malloc.h> 4486074Smurray#include <machine/bus.h> /* XXX Shouldn't really be required ! */ 4586074Smurray#include <sys/random.h> 4686074Smurray#include <sys/rman.h> 4786074Smurray 4886074Smurray#include <net/if.h> 4953812Salfred#include <net/if_types.h> 5053812Salfred#include <net/netisr.h> 5153812Salfred#include <net/route.h> 5253812Salfred#ifdef INET 5353812Salfred#include <netinet/in.h> 5453812Salfred#endif 5553812Salfred#include <net/bpf.h> 5653812Salfred#include <net/if_tunvar.h> 5753812Salfred#include <net/if_tun.h> 5853812Salfred 5953812Salfred#define TUNDEBUG if (tundebug) if_printf 6053812Salfred#define TUNNAME "tun" 6153812Salfred 6253812Salfredstatic MALLOC_DEFINE(M_TUN, TUNNAME, "Tunnel Interface"); 6353812Salfredstatic int tundebug = 0; 6453812Salfredstatic struct tun_softc *tunhead = NULL; 6553812Salfredstatic struct rman tununits; 6653812Salfredstatic udev_t tunbasedev = NOUDEV; 6753812SalfredSYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, ""); 6857686Ssheldonh 6957686Ssheldonhstatic void tunclone(void *arg, char *name, int namelen, dev_t *dev); 7053812Salfredstatic void tuncreate(dev_t dev); 7153812Salfredstatic int tunifioctl(struct ifnet *, u_long, caddr_t); 7253812Salfredstatic int tuninit(struct ifnet *); 7353812Salfredstatic int tunmodevent(module_t, int, void *); 7453812Salfredstatic int tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 7557686Ssheldonh struct rtentry *rt); 7657686Ssheldonhstatic void tunstart(struct ifnet *); 7753812Salfred 7853812Salfredstatic d_open_t tunopen; 7953812Salfredstatic d_close_t tunclose; 8053812Salfredstatic d_read_t tunread; 8153812Salfredstatic d_write_t tunwrite; 8253812Salfredstatic d_ioctl_t tunioctl; 8353812Salfredstatic d_poll_t tunpoll; 8453812Salfred 8553812Salfred#define CDEV_MAJOR 52 8653812Salfredstatic struct cdevsw tun_cdevsw = { 8753812Salfred .d_open = tunopen, 8853812Salfred .d_close = tunclose, 8953812Salfred .d_read = tunread, 9053812Salfred .d_write = tunwrite, 9153812Salfred .d_ioctl = tunioctl, 9253812Salfred .d_poll = tunpoll, 9353812Salfred .d_name = TUNNAME, 9457686Ssheldonh .d_maj = CDEV_MAJOR, 9557686Ssheldonh}; 9653812Salfred 9753812Salfredstatic void 9853812Salfredtunclone(void *arg, char *name, int namelen, dev_t *dev) 9953812Salfred{ 10053812Salfred struct resource *r; 10153812Salfred int err; 10253812Salfred int u; 103281455Skib 104281455Skib if (*dev != NODEV) 105281455Skib return; 106281455Skib 107281455Skib if (strcmp(name, TUNNAME) == 0) { 108281455Skib r = rman_reserve_resource(&tununits, 0, IF_MAXUNIT, 1, 109281455Skib RF_ALLOCATED | RF_ACTIVE, NULL); 110281455Skib u = rman_get_start(r); 111251639Sjilles err = rman_release_resource(r); 112251639Sjilles KASSERT(err == 0, ("Unexpected failure releasing resource")); 113251639Sjilles *dev = makedev(CDEV_MAJOR, unit2minor(u)); 114251639Sjilles if ((*dev)->si_flags & SI_NAMED) 115251639Sjilles return; /* Already make_dev()d */ 116251639Sjilles } else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1) 117281455Skib return; /* Don't recognise the name */ 118281455Skib 119281454Skib *dev = make_dev(&tun_cdevsw, unit2minor(u), 120281454Skib UID_ROOT, GID_WHEEL, 0600, "tun%d", u); 121281454Skib 122281454Skib /* 123281454Skib * All devices depend on tunbasedev so that we can simply 124281454Skib * destroy_dev() this device at module unload time to get 125281455Skib * rid of all our make_dev()d resources. 126281455Skib */ 127281455Skib if (tunbasedev == NOUDEV) 128281455Skib tunbasedev = (*dev)->si_udev; 129281455Skib else { 130281455Skib (*dev)->si_flags |= SI_CHEAPCLONE; 131281455Skib dev_depends(udev2dev(tunbasedev, 0), *dev); 132281455Skib } 133281455Skib} 134281455Skib 135281981Skibstatic int 136281455Skibtunmodevent(module_t mod, int type, void *data) 137281455Skib{ 138281455Skib static eventhandler_tag tag; 139281455Skib struct tun_softc *tp; 140281455Skib dev_t dev; 141281455Skib int err; 142281455Skib 143281455Skib switch (type) { 144281455Skib case MOD_LOAD: 145281455Skib tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000); 146281455Skib if (tag == NULL) 147281455Skib return (ENOMEM); 148281455Skib tununits.rm_type = RMAN_ARRAY; 149281455Skib tununits.rm_descr = "open if_tun units"; 150281455Skib err = rman_init(&tununits); 151281455Skib if (err != 0) { 152281455Skib EVENTHANDLER_DEREGISTER(dev_clone, tag); 153281455Skib return (err); 154281455Skib } 155281455Skib err = rman_manage_region(&tununits, 0, IF_MAXUNIT); 156281455Skib if (err != 0) { 157281455Skib printf("%s: tununits: rman_manage_region: Failed %d\n", 158281455Skib TUNNAME, err); 159281455Skib rman_fini(&tununits); 160281455Skib EVENTHANDLER_DEREGISTER(dev_clone, tag); 161281455Skib return (err); 162281455Skib } 163281981Skib break; 164281981Skib case MOD_UNLOAD: 165281455Skib err = rman_fini(&tununits); 166281455Skib if (err != 0) 167281455Skib return (err); 168281455Skib EVENTHANDLER_DEREGISTER(dev_clone, tag); 169281455Skib 17053812Salfred while (tunhead != NULL) { 17153812Salfred KASSERT((tunhead->tun_flags & TUN_OPEN) == 0, 17253812Salfred ("tununits is out of sync - unit %d", 17353812Salfred tunhead->tun_if.if_dunit)); 17453812Salfred tp = tunhead; 17557686Ssheldonh dev = makedev(tun_cdevsw.d_maj, 17657686Ssheldonh unit2minor(tp->tun_if.if_dunit)); 17753812Salfred KASSERT(dev->si_drv1 == tp, ("Bad makedev result")); 17853812Salfred tunhead = tp->next; 17953812Salfred bpfdetach(&tp->tun_if); 18057686Ssheldonh if_detach(&tp->tun_if); 18157686Ssheldonh KASSERT(dev->si_flags & SI_NAMED, ("Missing make_dev")); 18257686Ssheldonh free(tp, M_TUN); 18357686Ssheldonh } 18453812Salfred 18553812Salfred /* 18653812Salfred * Destroying tunbasedev results in all of our make_dev()s 18757686Ssheldonh * conveniently going away. 18857686Ssheldonh */ 18953812Salfred if (tunbasedev != NOUDEV) 19053812Salfred destroy_dev(udev2dev(tunbasedev, 0)); 19153812Salfred 19253812Salfred break; 193141846Sru } 19457686Ssheldonh return 0; 19557686Ssheldonh} 19653812Salfred 19753812Salfredstatic moduledata_t tun_mod = { 19853812Salfred "if_tun", 19953812Salfred tunmodevent, 20053812Salfred 0 20153812Salfred}; 20253812Salfred 20353812SalfredDECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 20457686Ssheldonh 20557686Ssheldonhstatic void 20653812Salfredtunstart(struct ifnet *ifp) 20753812Salfred{ 20853812Salfred struct tun_softc *tp = ifp->if_softc; 20953812Salfred 21053812Salfred if (tp->tun_flags & TUN_RWAIT) { 211281455Skib tp->tun_flags &= ~TUN_RWAIT; 212281455Skib wakeup(tp); 213281455Skib } 214281455Skib if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) 215281455Skib pgsigio(&tp->tun_sigio, SIGIO, 0); 216281455Skib selwakeup(&tp->tun_rsel); 217281455Skib} 218281455Skib 21953812Salfredstatic void 22053812Salfredtuncreate(dev_t dev) 22153812Salfred{ 22253812Salfred struct tun_softc *sc; 22353812Salfred struct ifnet *ifp; 22453812Salfred 22553812Salfred if (!(dev->si_flags & SI_NAMED)) 22653812Salfred dev = make_dev(&tun_cdevsw, minor(dev), 22753812Salfred UID_UUCP, GID_DIALER, 0600, "tun%d", dev2unit(dev)); 22853812Salfred 22953812Salfred MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO); 23053812Salfred sc->tun_flags = TUN_INITED; 23153812Salfred sc->next = tunhead; 23253812Salfred tunhead = sc; 23353812Salfred 23453812Salfred ifp = &sc->tun_if; 23553812Salfred if_initname(ifp, TUNNAME, dev2unit(dev)); 23653812Salfred ifp->if_mtu = TUNMTU; 23753812Salfred ifp->if_ioctl = tunifioctl; 23853812Salfred ifp->if_output = tunoutput; 23953812Salfred ifp->if_start = tunstart; 24053812Salfred ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 24153812Salfred ifp->if_type = IFT_PPP; 24253812Salfred ifp->if_snd.ifq_maxlen = ifqmaxlen; 24353812Salfred ifp->if_softc = sc; 244112542Scharnier if_attach(ifp); 24553812Salfred bpfattach(ifp, DLT_NULL, sizeof(u_int)); 246112542Scharnier dev->si_drv1 = sc; 24773093Sru} 248251639Sjilles 249251639Sjillesstatic int 25053812Salfredtunopen(dev_t dev, int flag, int mode, struct thread *td) 251147700Shmp{ 25271895Sru struct resource *r; 25381589Sru struct ifnet *ifp; 25481589Sru struct tun_softc *tp; 25581589Sru int unit; 25681589Sru 257 unit = dev2unit(dev); 258 if (unit > IF_MAXUNIT) 259 return (ENXIO); 260 261 r = rman_reserve_resource(&tununits, unit, unit, 1, 262 RF_ALLOCATED | RF_ACTIVE, NULL); 263 if (r == NULL) 264 return (EBUSY); 265 266 dev->si_flags &= ~SI_CHEAPCLONE; 267 268 tp = dev->si_drv1; 269 if (!tp) { 270 tuncreate(dev); 271 tp = dev->si_drv1; 272 } 273 KASSERT(!(tp->tun_flags & TUN_OPEN), ("Resource & flags out-of-sync")); 274 tp->tun_unit = r; 275 tp->tun_pid = td->td_proc->p_pid; 276 ifp = &tp->tun_if; 277 tp->tun_flags |= TUN_OPEN; 278 TUNDEBUG(ifp, "open\n"); 279 280 return (0); 281} 282 283/* 284 * tunclose - close the device - mark i/f down & delete 285 * routing info 286 */ 287static int 288tunclose(dev_t dev, int foo, int bar, struct thread *td) 289{ 290 struct tun_softc *tp; 291 struct ifnet *ifp; 292 int s; 293 int err; 294 295 tp = dev->si_drv1; 296 ifp = &tp->tun_if; 297 298 KASSERT(tp->tun_unit, ("Unit %d not marked open", tp->tun_if.if_dunit)); 299 tp->tun_flags &= ~TUN_OPEN; 300 tp->tun_pid = 0; 301 302 /* 303 * junk all pending output 304 */ 305 IF_DRAIN(&ifp->if_snd); 306 307 if (ifp->if_flags & IFF_UP) { 308 s = splimp(); 309 if_down(ifp); 310 splx(s); 311 } 312 313 if (ifp->if_flags & IFF_RUNNING) { 314 struct ifaddr *ifa; 315 316 s = splimp(); 317 /* find internet addresses and delete routes */ 318 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) 319 if (ifa->ifa_addr->sa_family == AF_INET) 320 rtinit(ifa, (int)RTM_DELETE, 321 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 322 ifp->if_flags &= ~IFF_RUNNING; 323 splx(s); 324 } 325 326 funsetown(&tp->tun_sigio); 327 selwakeup(&tp->tun_rsel); 328 329 TUNDEBUG (ifp, "closed\n"); 330 err = rman_release_resource(tp->tun_unit); 331 KASSERT(err == 0, ("Unit %d failed to release", tp->tun_if.if_dunit)); 332 333 return (0); 334} 335 336static int 337tuninit(struct ifnet *ifp) 338{ 339 struct tun_softc *tp = ifp->if_softc; 340 struct ifaddr *ifa; 341 int error = 0; 342 343 TUNDEBUG(ifp, "tuninit\n"); 344 345 ifp->if_flags |= IFF_UP | IFF_RUNNING; 346 getmicrotime(&ifp->if_lastchange); 347 348 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; 349 ifa = TAILQ_NEXT(ifa, ifa_link)) { 350 if (ifa->ifa_addr == NULL) 351 error = EFAULT; 352 /* XXX: Should maybe return straight off? */ 353 else { 354#ifdef INET 355 if (ifa->ifa_addr->sa_family == AF_INET) { 356 struct sockaddr_in *si; 357 358 si = (struct sockaddr_in *)ifa->ifa_addr; 359 if (si->sin_addr.s_addr) 360 tp->tun_flags |= TUN_IASET; 361 362 si = (struct sockaddr_in *)ifa->ifa_dstaddr; 363 if (si && si->sin_addr.s_addr) 364 tp->tun_flags |= TUN_DSTADDR; 365 } 366#endif 367 } 368 } 369 return (error); 370} 371 372/* 373 * Process an ioctl request. 374 */ 375static int 376tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 377{ 378 struct ifreq *ifr = (struct ifreq *)data; 379 struct tun_softc *tp = ifp->if_softc; 380 struct ifstat *ifs; 381 int error = 0, s; 382 383 s = splimp(); 384 switch(cmd) { 385 case SIOCGIFSTATUS: 386 ifs = (struct ifstat *)data; 387 if (tp->tun_pid) 388 sprintf(ifs->ascii + strlen(ifs->ascii), 389 "\tOpened by PID %d\n", tp->tun_pid); 390 break; 391 case SIOCSIFADDR: 392 error = tuninit(ifp); 393 TUNDEBUG(ifp, "address set, error=%d\n", error); 394 break; 395 case SIOCSIFDSTADDR: 396 error = tuninit(ifp); 397 TUNDEBUG(ifp, "destination address set, error=%d\n", error); 398 break; 399 case SIOCSIFMTU: 400 ifp->if_mtu = ifr->ifr_mtu; 401 TUNDEBUG(ifp, "mtu set\n"); 402 break; 403 case SIOCSIFFLAGS: 404 case SIOCADDMULTI: 405 case SIOCDELMULTI: 406 break; 407 default: 408 error = EINVAL; 409 } 410 splx(s); 411 return (error); 412} 413 414/* 415 * tunoutput - queue packets from higher level ready to put out. 416 */ 417static int 418tunoutput( 419 struct ifnet *ifp, 420 struct mbuf *m0, 421 struct sockaddr *dst, 422 struct rtentry *rt) 423{ 424 struct tun_softc *tp = ifp->if_softc; 425#ifdef MAC 426 int error; 427#endif 428 429 TUNDEBUG (ifp, "tunoutput\n"); 430 431#ifdef MAC 432 error = mac_check_ifnet_transmit(ifp, m0); 433 if (error) { 434 m_freem(m0); 435 return (error); 436 } 437#endif 438 439 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 440 TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags); 441 m_freem (m0); 442 return (EHOSTDOWN); 443 } 444 445 if ((ifp->if_flags & IFF_UP) != IFF_UP) { 446 m_freem (m0); 447 return (EHOSTDOWN); 448 } 449 450 /* BPF write needs to be handled specially */ 451 if (dst->sa_family == AF_UNSPEC) { 452 dst->sa_family = *(mtod(m0, int *)); 453 m0->m_len -= sizeof(int); 454 m0->m_pkthdr.len -= sizeof(int); 455 m0->m_data += sizeof(int); 456 } 457 458 if (ifp->if_bpf) { 459 /* 460 * We need to prepend the address family as 461 * a four byte field. Cons up a dummy header 462 * to pacify bpf. This is safe because bpf 463 * will only read from the mbuf (i.e., it won't 464 * try to free it or keep a pointer to it). 465 */ 466 struct mbuf m; 467 uint32_t af = dst->sa_family; 468 469 m.m_next = m0; 470 m.m_len = 4; 471 m.m_data = (char *)⁡ 472 473 BPF_MTAP(ifp, &m); 474 } 475 476 /* prepend sockaddr? this may abort if the mbuf allocation fails */ 477 if (tp->tun_flags & TUN_LMODE) { 478 /* allocate space for sockaddr */ 479 M_PREPEND(m0, dst->sa_len, M_DONTWAIT); 480 481 /* if allocation failed drop packet */ 482 if (m0 == NULL) { 483 ifp->if_iqdrops++; 484 ifp->if_oerrors++; 485 return (ENOBUFS); 486 } else { 487 bcopy(dst, m0->m_data, dst->sa_len); 488 } 489 } 490 491 if (tp->tun_flags & TUN_IFHEAD) { 492 /* Prepend the address family */ 493 M_PREPEND(m0, 4, M_DONTWAIT); 494 495 /* if allocation failed drop packet */ 496 if (m0 == NULL) { 497 ifp->if_iqdrops++; 498 ifp->if_oerrors++; 499 return (ENOBUFS); 500 } else 501 *(u_int32_t *)m0->m_data = htonl(dst->sa_family); 502 } else { 503#ifdef INET 504 if (dst->sa_family != AF_INET) 505#endif 506 { 507 m_freem(m0); 508 return (EAFNOSUPPORT); 509 } 510 } 511 512 if (! IF_HANDOFF(&ifp->if_snd, m0, ifp)) { 513 ifp->if_collisions++; 514 return (ENOBUFS); 515 } 516 ifp->if_opackets++; 517 return (0); 518} 519 520/* 521 * the cdevsw interface is now pretty minimal. 522 */ 523static int 524tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) 525{ 526 int s; 527 int error; 528 struct tun_softc *tp = dev->si_drv1; 529 struct tuninfo *tunp; 530 531 switch (cmd) { 532 case TUNSIFINFO: 533 tunp = (struct tuninfo *)data; 534 if (tunp->mtu < IF_MINMTU) 535 return (EINVAL); 536 if (tp->tun_if.if_mtu != tunp->mtu 537 && (error = suser(td)) != 0) 538 return (error); 539 tp->tun_if.if_mtu = tunp->mtu; 540 tp->tun_if.if_type = tunp->type; 541 tp->tun_if.if_baudrate = tunp->baudrate; 542 break; 543 case TUNGIFINFO: 544 tunp = (struct tuninfo *)data; 545 tunp->mtu = tp->tun_if.if_mtu; 546 tunp->type = tp->tun_if.if_type; 547 tunp->baudrate = tp->tun_if.if_baudrate; 548 break; 549 case TUNSDEBUG: 550 tundebug = *(int *)data; 551 break; 552 case TUNGDEBUG: 553 *(int *)data = tundebug; 554 break; 555 case TUNSLMODE: 556 if (*(int *)data) { 557 tp->tun_flags |= TUN_LMODE; 558 tp->tun_flags &= ~TUN_IFHEAD; 559 } else 560 tp->tun_flags &= ~TUN_LMODE; 561 break; 562 case TUNSIFHEAD: 563 if (*(int *)data) { 564 tp->tun_flags |= TUN_IFHEAD; 565 tp->tun_flags &= ~TUN_LMODE; 566 } else 567 tp->tun_flags &= ~TUN_IFHEAD; 568 break; 569 case TUNGIFHEAD: 570 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0; 571 break; 572 case TUNSIFMODE: 573 /* deny this if UP */ 574 if (tp->tun_if.if_flags & IFF_UP) 575 return(EBUSY); 576 577 switch (*(int *)data & ~IFF_MULTICAST) { 578 case IFF_POINTOPOINT: 579 case IFF_BROADCAST: 580 tp->tun_if.if_flags &= 581 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST); 582 tp->tun_if.if_flags |= *(int *)data; 583 break; 584 default: 585 return(EINVAL); 586 } 587 break; 588 case TUNSIFPID: 589 tp->tun_pid = curthread->td_proc->p_pid; 590 break; 591 case FIONBIO: 592 break; 593 case FIOASYNC: 594 if (*(int *)data) 595 tp->tun_flags |= TUN_ASYNC; 596 else 597 tp->tun_flags &= ~TUN_ASYNC; 598 break; 599 case FIONREAD: 600 s = splimp(); 601 if (tp->tun_if.if_snd.ifq_head) { 602 struct mbuf *mb = tp->tun_if.if_snd.ifq_head; 603 for( *(int *)data = 0; mb != 0; mb = mb->m_next) 604 *(int *)data += mb->m_len; 605 } else 606 *(int *)data = 0; 607 splx(s); 608 break; 609 case FIOSETOWN: 610 return (fsetown(*(int *)data, &tp->tun_sigio)); 611 612 case FIOGETOWN: 613 *(int *)data = fgetown(&tp->tun_sigio); 614 return (0); 615 616 /* This is deprecated, FIOSETOWN should be used instead. */ 617 case TIOCSPGRP: 618 return (fsetown(-(*(int *)data), &tp->tun_sigio)); 619 620 /* This is deprecated, FIOGETOWN should be used instead. */ 621 case TIOCGPGRP: 622 *(int *)data = -fgetown(&tp->tun_sigio); 623 return (0); 624 625 default: 626 return (ENOTTY); 627 } 628 return (0); 629} 630 631/* 632 * The cdevsw read interface - reads a packet at a time, or at 633 * least as much of a packet as can be read. 634 */ 635static int 636tunread(dev_t dev, struct uio *uio, int flag) 637{ 638 struct tun_softc *tp = dev->si_drv1; 639 struct ifnet *ifp = &tp->tun_if; 640 struct mbuf *m; 641 int error=0, len, s; 642 643 TUNDEBUG (ifp, "read\n"); 644 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 645 TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags); 646 return (EHOSTDOWN); 647 } 648 649 tp->tun_flags &= ~TUN_RWAIT; 650 651 s = splimp(); 652 do { 653 IF_DEQUEUE(&ifp->if_snd, m); 654 if (m == NULL) { 655 if (flag & IO_NDELAY) { 656 splx(s); 657 return (EWOULDBLOCK); 658 } 659 tp->tun_flags |= TUN_RWAIT; 660 if((error = tsleep(tp, PCATCH | (PZERO + 1), 661 "tunread", 0)) != 0) { 662 splx(s); 663 return (error); 664 } 665 } 666 } while (m == NULL); 667 splx(s); 668 669 while (m && uio->uio_resid > 0 && error == 0) { 670 len = min(uio->uio_resid, m->m_len); 671 if (len != 0) 672 error = uiomove(mtod(m, void *), len, uio); 673 m = m_free(m); 674 } 675 676 if (m) { 677 TUNDEBUG(ifp, "Dropping mbuf\n"); 678 m_freem(m); 679 } 680 return (error); 681} 682 683/* 684 * the cdevsw write interface - an atomic write is a packet - or else! 685 */ 686static int 687tunwrite(dev_t dev, struct uio *uio, int flag) 688{ 689 struct tun_softc *tp = dev->si_drv1; 690 struct ifnet *ifp = &tp->tun_if; 691 struct mbuf *top, **mp, *m; 692 int error=0, tlen, mlen; 693 uint32_t family; 694 int isr; 695 696 TUNDEBUG(ifp, "tunwrite\n"); 697 698 if ((ifp->if_flags & IFF_UP) != IFF_UP) 699 /* ignore silently */ 700 return (0); 701 702 if (uio->uio_resid == 0) 703 return (0); 704 705 if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) { 706 TUNDEBUG(ifp, "len=%d!\n", uio->uio_resid); 707 return (EIO); 708 } 709 tlen = uio->uio_resid; 710 711 /* get a header mbuf */ 712 MGETHDR(m, M_DONTWAIT, MT_DATA); 713 if (m == NULL) 714 return (ENOBUFS); 715 mlen = MHLEN; 716 717 top = 0; 718 mp = ⊤ 719 while (error == 0 && uio->uio_resid > 0) { 720 m->m_len = min(mlen, uio->uio_resid); 721 error = uiomove(mtod(m, void *), m->m_len, uio); 722 *mp = m; 723 mp = &m->m_next; 724 if (uio->uio_resid > 0) { 725 MGET (m, M_DONTWAIT, MT_DATA); 726 if (m == 0) { 727 error = ENOBUFS; 728 break; 729 } 730 mlen = MLEN; 731 } 732 } 733 if (error) { 734 if (top) 735 m_freem (top); 736 ifp->if_ierrors++; 737 return (error); 738 } 739 740 top->m_pkthdr.len = tlen; 741 top->m_pkthdr.rcvif = ifp; 742#ifdef MAC 743 mac_create_mbuf_from_ifnet(ifp, top); 744#endif 745 746 if (ifp->if_bpf) { 747 if (tp->tun_flags & TUN_IFHEAD) { 748 /* 749 * Conveniently, we already have a 4-byte address 750 * family prepended to our packet ! 751 * Inconveniently, it's in the wrong byte order ! 752 */ 753 if ((top = m_pullup(top, sizeof(family))) == NULL) 754 return (ENOBUFS); 755 *mtod(top, u_int32_t *) = 756 ntohl(*mtod(top, u_int32_t *)); 757 BPF_MTAP(ifp, top); 758 *mtod(top, u_int32_t *) = 759 htonl(*mtod(top, u_int32_t *)); 760 } else { 761 /* 762 * We need to prepend the address family as 763 * a four byte field. Cons up a dummy header 764 * to pacify bpf. This is safe because bpf 765 * will only read from the mbuf (i.e., it won't 766 * try to free it or keep a pointer to it). 767 */ 768 struct mbuf m; 769 uint32_t af = AF_INET; 770 771 m.m_next = top; 772 m.m_len = 4; 773 m.m_data = (char *)⁡ 774 775 BPF_MTAP(ifp, &m); 776 } 777 } 778 779 if (tp->tun_flags & TUN_IFHEAD) { 780 if (top->m_len < sizeof(family) && 781 (top = m_pullup(top, sizeof(family))) == NULL) 782 return (ENOBUFS); 783 family = ntohl(*mtod(top, u_int32_t *)); 784 m_adj(top, sizeof(family)); 785 } else 786 family = AF_INET; 787 788 switch (family) { 789#ifdef INET 790 case AF_INET: 791 isr = NETISR_IP; 792 break; 793#endif 794#ifdef INET6 795 case AF_INET6: 796 isr = NETISR_IPV6; 797 break; 798#endif 799#ifdef IPX 800 case AF_IPX: 801 isr = NETISR_IPX; 802 break; 803#endif 804#ifdef NETATALK 805 case AF_APPLETALK: 806 isr = NETISR_ATALK2; 807 break; 808#endif 809 default: 810 m_freem(m); 811 return (EAFNOSUPPORT); 812 } 813 /* First chunk of an mbuf contains good junk */ 814 if (harvest.point_to_point) 815 random_harvest(m, 16, 3, 0, RANDOM_NET); 816 ifp->if_ibytes += top->m_pkthdr.len; 817 ifp->if_ipackets++; 818 netisr_dispatch(isr, top); 819 return (0); 820} 821 822/* 823 * tunpoll - the poll interface, this is only useful on reads 824 * really. The write detect always returns true, write never blocks 825 * anyway, it either accepts the packet or drops it. 826 */ 827static int 828tunpoll(dev_t dev, int events, struct thread *td) 829{ 830 int s; 831 struct tun_softc *tp = dev->si_drv1; 832 struct ifnet *ifp = &tp->tun_if; 833 int revents = 0; 834 835 s = splimp(); 836 TUNDEBUG(ifp, "tunpoll\n"); 837 838 if (events & (POLLIN | POLLRDNORM)) { 839 if (ifp->if_snd.ifq_len > 0) { 840 TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len); 841 revents |= events & (POLLIN | POLLRDNORM); 842 } else { 843 TUNDEBUG(ifp, "tunpoll waiting\n"); 844 selrecord(td, &tp->tun_rsel); 845 } 846 } 847 if (events & (POLLOUT | POLLWRNORM)) 848 revents |= events & (POLLOUT | POLLWRNORM); 849 850 splx(s); 851 return (revents); 852} 853