1 /* $NetBSD: if_tun.c,v 1.16 1995/03/08 02:57:09 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 it's 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/select mode of 14 * operation though. 15 */ 16 17 #include "tun.h" 18 #if NTUN > 0 19 20 #include <sys/param.h> 21 #include <sys/proc.h> 22 #include <sys/systm.h> 23 #include <sys/mbuf.h> 24 #include <sys/buf.h> 25 #include <sys/protosw.h> 26 #include <sys/socket.h> 27 #include <sys/ioctl.h> 28 #include <sys/errno.h> 29 #include <sys/syslog.h> 30 #include <sys/select.h> 31 #include <sys/file.h> 32 33 #include <machine/cpu.h> 34 35 #include <net/if.h> 36 #include <net/netisr.h> 37 #include <net/route.h> 38 39 #ifdef INET 40 #include <netinet/in.h> 41 #include <netinet/in_systm.h> 42 #include <netinet/in_var.h> 43 #include <netinet/ip.h> 44 #include <netinet/if_ether.h> 45 #endif 46 47 #ifdef NS 48 #include <netns/ns.h> 49 #include <netns/ns_if.h> 50 #endif 51 52 #include "bpfilter.h" 53 #if NBPFILTER > 0 54 #include <sys/time.h> 55 #include <net/bpf.h> 56 #endif 57 58 #include <net/if_tun.h> 59 60 #define TUNDEBUG if (tundebug) printf 61 int tundebug = 0; 62 63 struct tun_softc tunctl[NTUN]; 64 extern int ifqmaxlen; 65 66 int tunopen __P((dev_t, int, int, struct proc *)); 67 int tunclose __P((dev_t, int)); 68 int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, 69 struct rtentry *rt)); 70 int tunread __P((dev_t, struct uio *)); 71 int tunwrite __P((dev_t, struct uio *)); 72 int tuncioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); 73 int tunioctl __P((struct ifnet *, u_long, caddr_t)); 74 int tunselect __P((dev_t, int)); 75 void tunattach __P((int)); 76 77 static int tuninit __P((int)); 78 79 void 80 tunattach(unused) 81 int unused; 82 { 83 register int i; 84 struct ifnet *ifp; 85 struct sockaddr_in *sin; 86 87 for (i = 0; i < NTUN; i++) { 88 tunctl[i].tun_flags = TUN_INITED; 89 90 ifp = &tunctl[i].tun_if; 91 ifp->if_unit = i; 92 ifp->if_name = "tun"; 93 ifp->if_mtu = TUNMTU; 94 ifp->if_ioctl = tunioctl; 95 ifp->if_output = tunoutput; 96 ifp->if_flags = IFF_POINTOPOINT; 97 ifp->if_snd.ifq_maxlen = ifqmaxlen; 98 ifp->if_collisions = 0; 99 ifp->if_ierrors = 0; 100 ifp->if_oerrors = 0; 101 ifp->if_ipackets = 0; 102 ifp->if_opackets = 0; 103 if_attach(ifp); 104 #if NBPFILTER > 0 105 bpfattach(&tunctl[i].tun_bpf, ifp, DLT_NULL, sizeof(u_int32_t)); 106 #endif 107 } 108 } 109 110 /* 111 * tunnel open - must be superuser & the device must be 112 * configured in 113 */ 114 int 115 tunopen(dev, flag, mode, p) 116 dev_t dev; 117 int flag, mode; 118 struct proc *p; 119 { 120 struct ifnet *ifp; 121 struct tun_softc *tp; 122 register int unit, error; 123 124 if (error = suser(p->p_ucred, &p->p_acflag)) 125 return (error); 126 127 if ((unit = minor(dev)) >= NTUN) 128 return (ENXIO); 129 tp = &tunctl[unit]; 130 if (tp->tun_flags & TUN_OPEN) 131 return ENXIO; 132 ifp = &tp->tun_if; 133 tp->tun_flags |= TUN_OPEN; 134 TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit); 135 return (0); 136 } 137 138 /* 139 * tunclose - close the device - mark i/f down & delete 140 * routing info 141 */ 142 int 143 tunclose(dev, flag) 144 dev_t dev; 145 int flag; 146 { 147 register int unit = minor(dev), s; 148 struct tun_softc *tp = &tunctl[unit]; 149 struct ifnet *ifp = &tp->tun_if; 150 struct mbuf *m; 151 152 tp->tun_flags &= ~TUN_OPEN; 153 154 /* 155 * junk all pending output 156 */ 157 do { 158 s = splimp(); 159 IF_DEQUEUE(&ifp->if_snd, m); 160 splx(s); 161 if (m) 162 m_freem(m); 163 } while (m); 164 165 if (ifp->if_flags & IFF_UP) { 166 s = splimp(); 167 if_down(ifp); 168 if (ifp->if_flags & IFF_RUNNING) { 169 /* find internet addresses and delete routes */ 170 register struct ifaddr *ifa; 171 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 172 if (ifa->ifa_addr->sa_family == AF_INET) { 173 rtinit(ifa, (int)RTM_DELETE, 174 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 175 } 176 } 177 } 178 splx(s); 179 } 180 tp->tun_pgrp = 0; 181 selwakeup(&tp->tun_rsel); 182 183 TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit); 184 return (0); 185 } 186 187 static int 188 tuninit(unit) 189 int unit; 190 { 191 struct tun_softc *tp = &tunctl[unit]; 192 struct ifnet *ifp = &tp->tun_if; 193 register struct ifaddr *ifa; 194 195 TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 196 197 ifp->if_flags |= IFF_UP | IFF_RUNNING; 198 199 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 200 if (ifa->ifa_addr->sa_family == AF_INET) { 201 struct sockaddr_in *si; 202 203 si = (struct sockaddr_in *)ifa->ifa_addr; 204 if (si && si->sin_addr.s_addr) 205 tp->tun_flags |= TUN_IASET; 206 207 si = (struct sockaddr_in *)ifa->ifa_dstaddr; 208 if (si && si->sin_addr.s_addr) 209 tp->tun_flags |= TUN_DSTADDR; 210 } 211 212 return 0; 213 } 214 215 /* 216 * Process an ioctl request. 217 */ 218 int 219 tunioctl(ifp, cmd, data) 220 struct ifnet *ifp; 221 u_long cmd; 222 caddr_t data; 223 { 224 struct tun_softc *tp = &tunctl[ifp->if_unit]; 225 int error = 0, s; 226 227 s = splimp(); 228 switch(cmd) { 229 case SIOCSIFADDR: 230 tuninit(ifp->if_unit); 231 TUNDEBUG("%s%d: address set\n", 232 ifp->if_name, ifp->if_unit); 233 break; 234 case SIOCSIFDSTADDR: 235 tuninit(ifp->if_unit); 236 TUNDEBUG("%s%d: destination address set\n", 237 ifp->if_name, ifp->if_unit); 238 break; 239 default: 240 error = EINVAL; 241 } 242 splx(s); 243 return (error); 244 } 245 246 /* 247 * tunoutput - queue packets from higher level ready to put out. 248 */ 249 int 250 tunoutput(ifp, m0, dst, rt) 251 struct ifnet *ifp; 252 struct mbuf *m0; 253 struct sockaddr *dst; 254 struct rtentry *rt; 255 { 256 struct tun_softc *tp = &tunctl[ifp->if_unit]; 257 struct proc *p; 258 int s; 259 260 TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); 261 262 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 263 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 264 ifp->if_unit, tp->tun_flags); 265 m_freem (m0); 266 return EHOSTDOWN; 267 } 268 269 #if NBPFILTER > 0 270 if (tp->tun_bpf) { 271 /* 272 * We need to prepend the address family as 273 * a four byte field. Cons up a dummy header 274 * to pacify bpf. This is safe because bpf 275 * will only read from the mbuf (i.e., it won't 276 * try to free it or keep a pointer to it). 277 */ 278 struct mbuf m; 279 u_int32_t af = dst->sa_family; 280 281 m.m_next = m0; 282 m.m_len = sizeof(af); 283 m.m_data = (char *)⁡ 284 285 bpf_mtap(tp->tun_bpf, &m); 286 } 287 #endif 288 289 switch(dst->sa_family) { 290 #ifdef INET 291 case AF_INET: 292 s = splimp(); 293 if (IF_QFULL(&ifp->if_snd)) { 294 IF_DROP(&ifp->if_snd); 295 m_freem(m0); 296 splx(s); 297 ifp->if_collisions++; 298 return (ENOBUFS); 299 } 300 IF_ENQUEUE(&ifp->if_snd, m0); 301 splx(s); 302 ifp->if_opackets++; 303 break; 304 #endif 305 default: 306 m_freem(m0); 307 return EAFNOSUPPORT; 308 } 309 310 if (tp->tun_flags & TUN_RWAIT) { 311 tp->tun_flags &= ~TUN_RWAIT; 312 wakeup((caddr_t)tp); 313 } 314 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) { 315 if (tp->tun_pgrp > 0) 316 gsignal(tp->tun_pgrp, SIGIO); 317 else if (p = pfind(-tp->tun_pgrp)) 318 psignal(p, SIGIO); 319 } 320 selwakeup(&tp->tun_rsel); 321 return 0; 322 } 323 324 /* 325 * the cdevsw interface is now pretty minimal. 326 */ 327 int 328 tuncioctl(dev, cmd, data, flag, p) 329 dev_t dev; 330 u_long cmd; 331 caddr_t data; 332 int flag; 333 struct proc *p; 334 { 335 int unit = minor(dev), s; 336 struct tun_softc *tp = &tunctl[unit]; 337 338 switch (cmd) { 339 case TUNSDEBUG: 340 tundebug = *(int *)data; 341 break; 342 case TUNGDEBUG: 343 *(int *)data = tundebug; 344 break; 345 case FIONBIO: 346 if (*(int *)data) 347 tp->tun_flags |= TUN_NBIO; 348 else 349 tp->tun_flags &= ~TUN_NBIO; 350 break; 351 case FIOASYNC: 352 if (*(int *)data) 353 tp->tun_flags |= TUN_ASYNC; 354 else 355 tp->tun_flags &= ~TUN_ASYNC; 356 break; 357 case FIONREAD: 358 s = splimp(); 359 if (tp->tun_if.if_snd.ifq_head) 360 *(int *)data = tp->tun_if.if_snd.ifq_head->m_len; 361 else 362 *(int *)data = 0; 363 splx(s); 364 break; 365 case TIOCSPGRP: 366 tp->tun_pgrp = *(int *)data; 367 break; 368 case TIOCGPGRP: 369 *(int *)data = tp->tun_pgrp; 370 break; 371 default: 372 return (ENOTTY); 373 } 374 return (0); 375 } 376 377 /* 378 * The cdevsw read interface - reads a packet at a time, or at 379 * least as much of a packet as can be read. 380 */ 381 int 382 tunread(dev, uio) 383 dev_t dev; 384 struct uio *uio; 385 { 386 int unit = minor(dev); 387 struct tun_softc *tp = &tunctl[unit]; 388 struct ifnet *ifp = &tp->tun_if; 389 struct mbuf *m, *m0; 390 int error=0, len, s; 391 392 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit); 393 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 394 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 395 ifp->if_unit, tp->tun_flags); 396 return EHOSTDOWN; 397 } 398 399 tp->tun_flags &= ~TUN_RWAIT; 400 401 s = splimp(); 402 do { 403 IF_DEQUEUE(&ifp->if_snd, m0); 404 if (m0 == 0) { 405 if (tp->tun_flags & TUN_NBIO) { 406 splx(s); 407 return EWOULDBLOCK; 408 } 409 tp->tun_flags |= TUN_RWAIT; 410 tsleep((caddr_t)tp, PZERO + 1, "tunread", 0); 411 } 412 } while (m0 == 0); 413 splx(s); 414 415 while (m0 && uio->uio_resid > 0 && error == 0) { 416 len = min(uio->uio_resid, m0->m_len); 417 if (len == 0) 418 break; 419 error = uiomove(mtod(m0, caddr_t), len, uio); 420 MFREE(m0, m); 421 m0 = m; 422 } 423 424 if (m0) { 425 TUNDEBUG("Dropping mbuf\n"); 426 m_freem(m0); 427 } 428 return error; 429 } 430 431 /* 432 * the cdevsw write interface - an atomic write is a packet - or else! 433 */ 434 int 435 tunwrite(dev, uio) 436 dev_t dev; 437 struct uio *uio; 438 { 439 int unit = minor (dev); 440 struct ifnet *ifp = &tunctl[unit].tun_if; 441 struct mbuf *top, **mp, *m; 442 int error=0, s, tlen, mlen; 443 444 TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit); 445 446 if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) { 447 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit, 448 uio->uio_resid); 449 return EIO; 450 } 451 tlen = uio->uio_resid; 452 453 /* get a header mbuf */ 454 MGETHDR(m, M_DONTWAIT, MT_DATA); 455 if (m == NULL) 456 return ENOBUFS; 457 mlen = MHLEN; 458 459 top = 0; 460 mp = ⊤ 461 while (error == 0 && uio->uio_resid > 0) { 462 m->m_len = min(mlen, uio->uio_resid); 463 error = uiomove(mtod (m, caddr_t), m->m_len, uio); 464 *mp = m; 465 mp = &m->m_next; 466 if (uio->uio_resid > 0) { 467 MGET (m, M_DONTWAIT, MT_DATA); 468 if (m == 0) { 469 error = ENOBUFS; 470 break; 471 } 472 mlen = MLEN; 473 } 474 } 475 if (error) { 476 if (top) 477 m_freem (top); 478 return error; 479 } 480 481 top->m_pkthdr.len = tlen; 482 top->m_pkthdr.rcvif = ifp; 483 484 #if NBPFILTER > 0 485 if (tunctl[unit].tun_bpf) { 486 /* 487 * We need to prepend the address family as 488 * a four byte field. Cons up a dummy header 489 * to pacify bpf. This is safe because bpf 490 * will only read from the mbuf (i.e., it won't 491 * try to free it or keep a pointer to it). 492 */ 493 struct mbuf m; 494 u_int32_t af = AF_INET; 495 496 m.m_next = top; 497 m.m_len = sizeof(af); 498 m.m_data = (char *)⁡ 499 500 bpf_mtap(tunctl[unit].tun_bpf, &m); 501 } 502 #endif 503 504 s = splimp(); 505 if (IF_QFULL (&ipintrq)) { 506 IF_DROP(&ipintrq); 507 splx(s); 508 ifp->if_collisions++; 509 m_freem(top); 510 return ENOBUFS; 511 } 512 IF_ENQUEUE(&ipintrq, top); 513 splx(s); 514 ifp->if_ipackets++; 515 schednetisr(NETISR_IP); 516 return error; 517 } 518 519 /* 520 * tunselect - the select interface, this is only useful on reads 521 * really. The write detect always returns true, write never blocks 522 * anyway, it either accepts the packet or drops it. 523 */ 524 int 525 tunselect(dev, rw) 526 dev_t dev; 527 int rw; 528 { 529 int unit = minor(dev), s; 530 struct tun_softc *tp = &tunctl[unit]; 531 struct ifnet *ifp = &tp->tun_if; 532 533 s = splimp(); 534 TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit); 535 536 switch (rw) { 537 case FREAD: 538 if (ifp->if_snd.ifq_len > 0) { 539 splx(s); 540 TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name, 541 ifp->if_unit, ifp->if_snd.ifq_len); 542 return 1; 543 } 544 selrecord(curproc, &tp->tun_rsel); 545 break; 546 case FWRITE: 547 splx(s); 548 return 1; 549 } 550 splx(s); 551 TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit); 552 return 0; 553 } 554 555 #endif /* NTUN */ 556