if_tun.c revision 16258
177957Sbenno/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */ 277957Sbenno 377957Sbenno/* 477957Sbenno * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 577957Sbenno * Nottingham University 1987. 677957Sbenno * 777957Sbenno * This source may be freely distributed, however I would be interested 877957Sbenno * in any changes that are made. 977957Sbenno * 1077957Sbenno * This driver takes packets off the IP i/f and hands them up to a 1177957Sbenno * user process to have it's wicked way with. This driver has it's 1277957Sbenno * roots in a similar driver written by Phil Cockcroft (formerly) at 1377957Sbenno * UCL. This driver is based much more on read/write/select mode of 1477957Sbenno * operation though. 1577957Sbenno */ 1677957Sbenno 1777957Sbenno#include "tun.h" 1877957Sbenno#if NTUN > 0 1977957Sbenno 2077957Sbenno#include <sys/param.h> 2177957Sbenno#include <sys/proc.h> 2277957Sbenno#include <sys/systm.h> 2377957Sbenno#include <sys/mbuf.h> 2477957Sbenno#include <sys/buf.h> 2577957Sbenno#include <sys/protosw.h> 2677957Sbenno#include <sys/socket.h> 2777957Sbenno#include <sys/ioctl.h> 2877957Sbenno#include <sys/errno.h> 2977957Sbenno#include <sys/syslog.h> 3077957Sbenno#include <sys/select.h> 3177957Sbenno#include <sys/file.h> 3277957Sbenno#include <sys/signalvar.h> 3377957Sbenno#include <sys/kernel.h> 3477957Sbenno#include <sys/sysctl.h> 3577957Sbenno#ifdef DEVFS 3677957Sbenno#include <sys/devfsext.h> 3777957Sbenno#endif /*DEVFS*/ 3877957Sbenno#include <sys/conf.h> 3977957Sbenno 4077957Sbenno#include <net/if.h> 4177957Sbenno#include <net/netisr.h> 4277957Sbenno#include <net/route.h> 4377957Sbenno 4477957Sbenno#ifdef INET 4577957Sbenno#include <netinet/in.h> 4677957Sbenno#include <netinet/in_systm.h> 4777957Sbenno#include <netinet/in_var.h> 4877957Sbenno#include <netinet/ip.h> 4977957Sbenno#include <netinet/if_ether.h> 5077957Sbenno#endif 5177957Sbenno 5277957Sbenno#ifdef NS 5377957Sbenno#include <netns/ns.h> 5477957Sbenno#include <netns/ns_if.h> 5577957Sbenno#endif 5677957Sbenno 5777957Sbenno#include "bpfilter.h" 5877957Sbenno#if NBPFILTER > 0 5977957Sbenno#include <sys/time.h> 6077957Sbenno#include <net/bpf.h> 6177957Sbenno#endif 6277957Sbenno 6377957Sbenno#include <net/if_tun.h> 6477957Sbenno 6577957Sbennostatic void tunattach __P((void *)); 6677957SbennoPSEUDO_SET(tunattach, if_tun); 6777957Sbenno 6877957Sbenno#define TUNDEBUG if (tundebug) printf 6977957Sbennostatic int tundebug = 0; 7077957SbennoSYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, ""); 7177957Sbenno 7277957Sbennostatic struct tun_softc tunctl[NTUN]; 7377957Sbenno 7477957Sbennostatic int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, 7577957Sbenno struct rtentry *rt)); 7677957Sbennostatic int tunifioctl __P((struct ifnet *, int, caddr_t)); 7777957Sbennostatic int tuninit __P((int)); 7877957Sbenno 7977957Sbennostatic d_open_t tunopen; 8077957Sbennostatic d_close_t tunclose; 8177957Sbennostatic d_read_t tunread; 8277957Sbennostatic d_write_t tunwrite; 8377957Sbennostatic d_ioctl_t tunioctl; 8477957Sbennostatic d_select_t tunselect; 8577957Sbenno 8677957Sbenno#define CDEV_MAJOR 52 8777957Sbennostatic struct cdevsw tun_cdevsw = { 8877957Sbenno tunopen, tunclose, tunread, tunwrite, 8977957Sbenno tunioctl, nullstop, noreset, nodevtotty, 9077957Sbenno tunselect, nommap, nostrategy, "tun", NULL, -1 9177957Sbenno}; 9277957Sbenno 9377957Sbenno 9477957Sbennostatic tun_devsw_installed = 0; 9577957Sbenno#ifdef DEVFS 9677957Sbennostatic void *tun_devfs_token[NTUN]; 9777957Sbenno#endif 9877957Sbenno 9977957Sbennostatic void 10077957Sbennotunattach(dummy) 10177957Sbenno void *dummy; 10277957Sbenno{ 10377957Sbenno register int i; 10477957Sbenno struct ifnet *ifp; 10577957Sbenno dev_t dev; 10677957Sbenno 10777957Sbenno if( tun_devsw_installed ) return; 10877957Sbenno dev = makedev(CDEV_MAJOR, 0); 10977957Sbenno cdevsw_add(&dev,&tun_cdevsw, NULL); 11077957Sbenno tun_devsw_installed = 1; 11177957Sbenno for ( i = 0; i < NTUN; i++ ) { 11277957Sbenno#ifdef DEVFS 11377957Sbenno tun_devfs_token[i] = devfs_add_devswf(&tun_cdevsw, i, DV_CHR, 11477957Sbenno UID_UUCP, GID_DIALER, 11577957Sbenno 0600, "tun%d", i); 11677957Sbenno#endif 11777957Sbenno tunctl[i].tun_flags = TUN_INITED; 11877957Sbenno 11977957Sbenno ifp = &tunctl[i].tun_if; 12077957Sbenno ifp->if_unit = i; 12177957Sbenno ifp->if_name = "tun"; 12277957Sbenno ifp->if_mtu = TUNMTU; 12377957Sbenno ifp->if_ioctl = tunifioctl; 12477957Sbenno ifp->if_output = tunoutput; 12577957Sbenno ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 12677957Sbenno ifp->if_snd.ifq_maxlen = ifqmaxlen; 12777957Sbenno ifp->if_collisions = 0; 12877957Sbenno ifp->if_ierrors = 0; 12977957Sbenno ifp->if_oerrors = 0; 13077957Sbenno ifp->if_ipackets = 0; 13177957Sbenno ifp->if_opackets = 0; 13277957Sbenno if_attach(ifp); 13377957Sbenno#if NBPFILTER > 0 13477957Sbenno bpfattach(ifp, DLT_NULL, sizeof(u_int)); 13577957Sbenno#endif 13677957Sbenno } 13777957Sbenno} 13877957Sbenno 13977957Sbenno/* 14077957Sbenno * tunnel open - must be superuser & the device must be 14177957Sbenno * configured in 14277957Sbenno */ 14377957Sbennostatic int 14477957Sbennotunopen(dev, flag, mode, p) 14577957Sbenno dev_t dev; 14677957Sbenno int flag, mode; 14777957Sbenno struct proc *p; 14877957Sbenno{ 14977957Sbenno struct ifnet *ifp; 15077957Sbenno struct tun_softc *tp; 15177957Sbenno register int unit, error; 15277957Sbenno 15377957Sbenno error = suser(p->p_ucred, &p->p_acflag); 15477957Sbenno if (error) 15577957Sbenno return (error); 15677957Sbenno 15777957Sbenno if ((unit = minor(dev)) >= NTUN) 15877957Sbenno return (ENXIO); 15977957Sbenno tp = &tunctl[unit]; 16077957Sbenno if (tp->tun_flags & TUN_OPEN) 16177957Sbenno return EBUSY; 16277957Sbenno ifp = &tp->tun_if; 16377957Sbenno tp->tun_flags |= TUN_OPEN; 16477957Sbenno TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit); 16577957Sbenno return (0); 16677957Sbenno} 16777957Sbenno 16877957Sbenno/* 16977957Sbenno * tunclose - close the device - mark i/f down & delete 17077957Sbenno * routing info 17177957Sbenno */ 17277957Sbennostatic int 17377957Sbennotunclose(dev_t dev, int foo, int bar, struct proc *p) 17477957Sbenno{ 17577957Sbenno register int unit = minor(dev), s; 17677957Sbenno struct tun_softc *tp = &tunctl[unit]; 17777957Sbenno struct ifnet *ifp = &tp->tun_if; 17877957Sbenno struct mbuf *m; 17977957Sbenno 18077957Sbenno tp->tun_flags &= ~TUN_OPEN; 18177957Sbenno 18277957Sbenno /* 18377957Sbenno * junk all pending output 18477957Sbenno */ 18577957Sbenno do { 18677957Sbenno s = splimp(); 18777957Sbenno IF_DEQUEUE(&ifp->if_snd, m); 18877957Sbenno splx(s); 18977957Sbenno if (m) 19077957Sbenno m_freem(m); 19177957Sbenno } while (m); 19277957Sbenno 19377957Sbenno if (ifp->if_flags & IFF_UP) { 19477957Sbenno s = splimp(); 19577957Sbenno if_down(ifp); 19677957Sbenno if (ifp->if_flags & IFF_RUNNING) { 19777957Sbenno /* find internet addresses and delete routes */ 19877957Sbenno register struct ifaddr *ifa; 19977957Sbenno for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 20077957Sbenno if (ifa->ifa_addr->sa_family == AF_INET) { 20177957Sbenno rtinit(ifa, (int)RTM_DELETE, 20277957Sbenno tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 20377957Sbenno } 20477957Sbenno } 20577957Sbenno } 20677957Sbenno splx(s); 20777957Sbenno } 20877957Sbenno tp->tun_pgrp = 0; 20977957Sbenno selwakeup(&tp->tun_rsel); 21077957Sbenno 21177957Sbenno TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit); 21277957Sbenno return (0); 21377957Sbenno} 21477957Sbenno 21577957Sbennostatic int 21677957Sbennotuninit(unit) 21777957Sbenno int unit; 21877957Sbenno{ 21977957Sbenno struct tun_softc *tp = &tunctl[unit]; 22077957Sbenno struct ifnet *ifp = &tp->tun_if; 22177957Sbenno register struct ifaddr *ifa; 22277957Sbenno 22377957Sbenno TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 22477957Sbenno 22577957Sbenno ifp->if_flags |= IFF_UP | IFF_RUNNING; 22677957Sbenno 22777957Sbenno for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 22877957Sbenno if (ifa->ifa_addr->sa_family == AF_INET) { 22977957Sbenno struct sockaddr_in *si; 23077957Sbenno 23177957Sbenno si = (struct sockaddr_in *)ifa->ifa_addr; 23277957Sbenno if (si && si->sin_addr.s_addr) 23377957Sbenno tp->tun_flags |= TUN_IASET; 23477957Sbenno 23577957Sbenno si = (struct sockaddr_in *)ifa->ifa_dstaddr; 23677957Sbenno if (si && si->sin_addr.s_addr) 23777957Sbenno tp->tun_flags |= TUN_DSTADDR; 23877957Sbenno } 23977957Sbenno 24077957Sbenno return 0; 24177957Sbenno} 24277957Sbenno 24377957Sbenno/* 24477957Sbenno * Process an ioctl request. 24577957Sbenno */ 24677957Sbennoint 24777957Sbennotunifioctl(ifp, cmd, data) 24877957Sbenno struct ifnet *ifp; 24977957Sbenno int cmd; 25077957Sbenno caddr_t data; 25177957Sbenno{ 25277957Sbenno register struct ifreq *ifr = (struct ifreq *)data; 25377957Sbenno int error = 0, s; 25477957Sbenno 25577957Sbenno s = splimp(); 25677957Sbenno switch(cmd) { 257 case SIOCSIFADDR: 258 tuninit(ifp->if_unit); 259 TUNDEBUG("%s%d: address set\n", 260 ifp->if_name, ifp->if_unit); 261 break; 262 case SIOCSIFDSTADDR: 263 tuninit(ifp->if_unit); 264 TUNDEBUG("%s%d: destination address set\n", 265 ifp->if_name, ifp->if_unit); 266 break; 267 case SIOCADDMULTI: 268 case SIOCDELMULTI: 269 if (ifr == 0) { 270 error = EAFNOSUPPORT; /* XXX */ 271 break; 272 } 273 switch (ifr->ifr_addr.sa_family) { 274 275#ifdef INET 276 case AF_INET: 277 break; 278#endif 279 280 default: 281 error = EAFNOSUPPORT; 282 break; 283 } 284 break; 285 286 287 default: 288 error = EINVAL; 289 } 290 splx(s); 291 return (error); 292} 293 294/* 295 * tunoutput - queue packets from higher level ready to put out. 296 */ 297int 298tunoutput(ifp, m0, dst, rt) 299 struct ifnet *ifp; 300 struct mbuf *m0; 301 struct sockaddr *dst; 302 struct rtentry *rt; 303{ 304 struct tun_softc *tp = &tunctl[ifp->if_unit]; 305 struct proc *p; 306 int s; 307 308 TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); 309 310 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 311 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 312 ifp->if_unit, tp->tun_flags); 313 m_freem (m0); 314 return EHOSTDOWN; 315 } 316 317#if NBPFILTER > 0 318 /* BPF write needs to be handled specially */ 319 if (dst->sa_family == AF_UNSPEC) { 320 dst->sa_family = *(mtod(m0, int *)); 321 m0->m_len -= sizeof(int); 322 m0->m_pkthdr.len -= sizeof(int); 323 m0->m_data += sizeof(int); 324 } 325 326 if (ifp->if_bpf) { 327 /* 328 * We need to prepend the address family as 329 * a four byte field. Cons up a dummy header 330 * to pacify bpf. This is safe because bpf 331 * will only read from the mbuf (i.e., it won't 332 * try to free it or keep a pointer to it). 333 */ 334 struct mbuf m; 335 u_int af = dst->sa_family; 336 337 m.m_next = m0; 338 m.m_len = 4; 339 m.m_data = (char *)⁡ 340 341 bpf_mtap(ifp, &m); 342 } 343#endif 344 345 switch(dst->sa_family) { 346#ifdef INET 347 case AF_INET: 348 s = splimp(); 349 if (IF_QFULL(&ifp->if_snd)) { 350 IF_DROP(&ifp->if_snd); 351 m_freem(m0); 352 splx(s); 353 ifp->if_collisions++; 354 return (ENOBUFS); 355 } 356 ifp->if_obytes += m0->m_pkthdr.len; 357 IF_ENQUEUE(&ifp->if_snd, m0); 358 splx(s); 359 ifp->if_opackets++; 360 break; 361#endif 362 default: 363 m_freem(m0); 364 return EAFNOSUPPORT; 365 } 366 367 if (tp->tun_flags & TUN_RWAIT) { 368 tp->tun_flags &= ~TUN_RWAIT; 369 wakeup((caddr_t)tp); 370 } 371 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) { 372 if (tp->tun_pgrp > 0) 373 gsignal(tp->tun_pgrp, SIGIO); 374 else if ((p = pfind(-tp->tun_pgrp)) != 0) 375 psignal(p, SIGIO); 376 } 377 selwakeup(&tp->tun_rsel); 378 return 0; 379} 380 381/* 382 * the cdevsw interface is now pretty minimal. 383 */ 384static int 385tunioctl(dev, cmd, data, flag, p) 386 dev_t dev; 387 int cmd; 388 caddr_t data; 389 int flag; 390 struct proc *p; 391{ 392 int unit = minor(dev), s; 393 struct tun_softc *tp = &tunctl[unit]; 394 struct tuninfo *tunp; 395 396 switch (cmd) { 397 case TUNSIFINFO: 398 tunp = (struct tuninfo *)data; 399 tp->tun_if.if_mtu = tunp->mtu; 400 tp->tun_if.if_type = tunp->type; 401 tp->tun_if.if_baudrate = tunp->baudrate; 402 break; 403 case TUNGIFINFO: 404 tunp = (struct tuninfo *)data; 405 tunp->mtu = tp->tun_if.if_mtu; 406 tunp->type = tp->tun_if.if_type; 407 tunp->baudrate = tp->tun_if.if_baudrate; 408 break; 409 case TUNSDEBUG: 410 tundebug = *(int *)data; 411 break; 412 case TUNGDEBUG: 413 *(int *)data = tundebug; 414 break; 415 case FIONBIO: 416 if (*(int *)data) 417 tp->tun_flags |= TUN_NBIO; 418 else 419 tp->tun_flags &= ~TUN_NBIO; 420 break; 421 case FIOASYNC: 422 if (*(int *)data) 423 tp->tun_flags |= TUN_ASYNC; 424 else 425 tp->tun_flags &= ~TUN_ASYNC; 426 break; 427 case FIONREAD: 428 s = splimp(); 429 if (tp->tun_if.if_snd.ifq_head) { 430 struct mbuf *mb = tp->tun_if.if_snd.ifq_head; 431 for( *(int *)data = 0; mb != 0; mb = mb->m_next) 432 *(int *)data += mb->m_len; 433 } else 434 *(int *)data = 0; 435 splx(s); 436 break; 437 case TIOCSPGRP: 438 tp->tun_pgrp = *(int *)data; 439 break; 440 case TIOCGPGRP: 441 *(int *)data = tp->tun_pgrp; 442 break; 443 default: 444 return (ENOTTY); 445 } 446 return (0); 447} 448 449/* 450 * The cdevsw read interface - reads a packet at a time, or at 451 * least as much of a packet as can be read. 452 */ 453static int 454tunread(dev_t dev, struct uio *uio, int flag) 455{ 456 int unit = minor(dev); 457 struct tun_softc *tp = &tunctl[unit]; 458 struct ifnet *ifp = &tp->tun_if; 459 struct mbuf *m, *m0; 460 int error=0, len, s; 461 462 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit); 463 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 464 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 465 ifp->if_unit, tp->tun_flags); 466 return EHOSTDOWN; 467 } 468 469 tp->tun_flags &= ~TUN_RWAIT; 470 471 s = splimp(); 472 do { 473 IF_DEQUEUE(&ifp->if_snd, m0); 474 if (m0 == 0) { 475 if (tp->tun_flags & TUN_NBIO) { 476 splx(s); 477 return EWOULDBLOCK; 478 } 479 tp->tun_flags |= TUN_RWAIT; 480 tsleep((caddr_t)tp, PZERO + 1, "tunread", 0); 481 } 482 } while (m0 == 0); 483 splx(s); 484 485 while (m0 && uio->uio_resid > 0 && error == 0) { 486 len = min(uio->uio_resid, m0->m_len); 487 if (len == 0) 488 break; 489 error = uiomove(mtod(m0, caddr_t), len, uio); 490 MFREE(m0, m); 491 m0 = m; 492 } 493 494 if (m0) { 495 TUNDEBUG("Dropping mbuf\n"); 496 m_freem(m0); 497 } 498 return error; 499} 500 501/* 502 * the cdevsw write interface - an atomic write is a packet - or else! 503 */ 504static int 505tunwrite(dev_t dev, struct uio *uio, int flag) 506{ 507 int unit = minor (dev); 508 struct ifnet *ifp = &tunctl[unit].tun_if; 509 struct mbuf *top, **mp, *m; 510 int error=0, s, tlen, mlen; 511 512 TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit); 513 514 if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) { 515 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit, 516 uio->uio_resid); 517 return EIO; 518 } 519 tlen = uio->uio_resid; 520 521 /* get a header mbuf */ 522 MGETHDR(m, M_DONTWAIT, MT_DATA); 523 if (m == NULL) 524 return ENOBUFS; 525 mlen = MHLEN; 526 527 top = 0; 528 mp = ⊤ 529 while (error == 0 && uio->uio_resid > 0) { 530 m->m_len = min(mlen, uio->uio_resid); 531 error = uiomove(mtod (m, caddr_t), m->m_len, uio); 532 *mp = m; 533 mp = &m->m_next; 534 if (uio->uio_resid > 0) { 535 MGET (m, M_DONTWAIT, MT_DATA); 536 if (m == 0) { 537 error = ENOBUFS; 538 break; 539 } 540 mlen = MLEN; 541 } 542 } 543 if (error) { 544 if (top) 545 m_freem (top); 546 return error; 547 } 548 549 top->m_pkthdr.len = tlen; 550 top->m_pkthdr.rcvif = ifp; 551 552#if NBPFILTER > 0 553 if (ifp->if_bpf) { 554 /* 555 * We need to prepend the address family as 556 * a four byte field. Cons up a dummy header 557 * to pacify bpf. This is safe because bpf 558 * will only read from the mbuf (i.e., it won't 559 * try to free it or keep a pointer to it). 560 */ 561 struct mbuf m; 562 u_int af = AF_INET; 563 564 m.m_next = top; 565 m.m_len = 4; 566 m.m_data = (char *)⁡ 567 568 bpf_mtap(ifp, &m); 569 } 570#endif 571 572 s = splimp(); 573 if (IF_QFULL (&ipintrq)) { 574 IF_DROP(&ipintrq); 575 splx(s); 576 ifp->if_collisions++; 577 m_freem(top); 578 return ENOBUFS; 579 } 580 IF_ENQUEUE(&ipintrq, top); 581 splx(s); 582 ifp->if_ibytes += tlen; 583 ifp->if_ipackets++; 584 schednetisr(NETISR_IP); 585 return error; 586} 587 588/* 589 * tunselect - the select interface, this is only useful on reads 590 * really. The write detect always returns true, write never blocks 591 * anyway, it either accepts the packet or drops it. 592 */ 593static int 594tunselect(dev_t dev, int rw, struct proc *p) 595{ 596 int unit = minor(dev), s; 597 struct tun_softc *tp = &tunctl[unit]; 598 struct ifnet *ifp = &tp->tun_if; 599 600 s = splimp(); 601 TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit); 602 603 switch (rw) { 604 case FREAD: 605 if (ifp->if_snd.ifq_len > 0) { 606 splx(s); 607 TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name, 608 ifp->if_unit, ifp->if_snd.ifq_len); 609 return 1; 610 } 611 selrecord(p, &tp->tun_rsel); 612 break; 613 case FWRITE: 614 splx(s); 615 return 1; 616 } 617 splx(s); 618 TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit); 619 return 0; 620} 621 622 623#endif /* NTUN */ 624