1 /* UNFINISHED CONVERSION TO 386BSD -wfj */ 2 3 /* if_tun.c - tunnel interface module & driver */ 4 5 /* 6 * Copyright (c) 1988, Julian Onions. 7 * 8 * This source may be freely distributed, however I would be interested 9 * in any changes that are made. 10 */ 11 12 /* 13 * 90/02/06 15:03 - Fixed a bug in where TIOCGPGRP and TIOCSPGRP were 14 * mixed up. Anders Klemets - klemets@sics.se 15 * 16 * $Id: if_tun.c,v 1.5 1993/08/09 01:19:38 deraadt Exp $ 17 * 18 */ 19 20 #include "tun.h" 21 #if NTUN > 0 22 23 /* 24 * Tunnel driver. 25 * 26 * This driver takes packets off the IP i/f and hands them up to a 27 * user process to have it's wicked way with. This driver has it's 28 * roots in a similar driver written by Phil Cockcroft (formerly) at 29 * UCL. This driver is based much more on read/write/select mode of 30 * operation though. 31 * 32 * Julian Onions <jpo@cs.nott.ac.uk> 33 * Nottingham University 1987. 34 */ 35 36 #include "param.h" 37 #include "systm.h" 38 #include "mbuf.h" 39 #include "buf.h" 40 #include "protosw.h" 41 #include "socket.h" 42 #include "ioctl.h" 43 #include "errno.h" 44 #include "syslog.h" 45 #include "select.h" 46 47 #include "net/if.h" 48 #include "net/netisr.h" 49 #include "net/route.h" 50 51 #ifdef INET 52 #include "netinet/in.h" 53 #include "netinet/in_systm.h" 54 #include "netinet/in_var.h" 55 #include "netinet/ip.h" 56 #include "netinet/if_ether.h" 57 #endif 58 59 #ifdef NS 60 #include "netns/ns.h" 61 #include "netns/ns_if.h" 62 #endif 63 64 #define TUNDEBUG if (tundebug) printf 65 66 int tundebug = 0; 67 struct tunctl 68 { 69 u_short tun_flags; /* misc flags */ 70 struct ifnet tun_if; /* the interface */ 71 int tun_pgrp; /* the process group - if any */ 72 struct selinfo tun_rsel; /* read select */ 73 struct selinfo tun_wsel; /* write select (not used) */ 74 } tunctl[NTUN]; 75 76 extern int ifqmaxlen; 77 78 int tunoutput (), tunioctl (), tuninit (); 79 80 /* tunnel open - must be superuser & the device must be configured in */ 81 tunopen (dev, flag) 82 dev_t dev; 83 { 84 struct proc *p = curproc; /* XXX */ 85 register int unit; 86 struct tunctl *tp; 87 register struct ifnet *ifp; 88 int error; 89 90 if (error = suser(p->p_ucred, &p->p_acflag)) 91 return (error); 92 93 if ((unit = minor (dev)) >= NTUN) 94 return (ENXIO); 95 tp = &tunctl[unit]; 96 if (tp->tun_flags & TUN_OPEN) 97 return ENXIO; 98 if ((tp->tun_flags & TUN_INITED) == 0) { 99 tp->tun_flags = TUN_INITED; 100 tunattach (unit); 101 } 102 ifp = &tp->tun_if; 103 tp->tun_flags |= TUN_OPEN; 104 TUNDEBUG ("%s%d: open\n", ifp->if_name, ifp->if_unit); 105 return (0); 106 } 107 108 /* tunclose - close the device - mark i/f down & delete routing info */ 109 tunclose (dev, flag) 110 dev_t dev; 111 { 112 int s; 113 register int unit = minor (dev); 114 register struct tunctl *tp = &tunctl[unit]; 115 register struct ifnet *ifp = &tp->tun_if; 116 register struct mbuf *m; 117 118 tp->tun_flags &= TUN_INITED; 119 120 /* 121 * junk all pending output 122 */ 123 do { 124 s = splimp (); 125 IF_DEQUEUE (&ifp->if_snd, m); 126 splx (s); 127 if (m) /* actually - m_freem checks this - but what the hell */ 128 m_freem (m); 129 } while (m != 0); 130 if (ifp->if_flags & IFF_UP) { 131 s = splimp (); 132 if_down (ifp); 133 if (ifp->if_flags & IFF_RUNNING) 134 rtinit (ifp->if_addrlist, (int)SIOCDELRT, RTF_HOST); 135 splx (s); 136 } 137 tp -> tun_pgrp = 0; 138 if (tp -> tun_rsel) 139 selwakeup (&tp->tun_rsel); 140 141 tp -> tun_rsel = tp -> tun_wsel = (struct proc *)0; 142 143 TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit); 144 return (0); 145 } 146 147 /* 148 * attach an interface N.B. argument is not same as other drivers 149 */ 150 int 151 tunattach (unit) 152 int unit; 153 { 154 register struct ifnet *ifp = &tunctl[unit].tun_if; 155 register struct sockaddr_in *sin; 156 157 ifp->if_unit = unit; 158 ifp->if_name = "tun"; 159 ifp->if_mtu = TUNMTU; 160 ifp->if_ioctl = tunioctl; 161 ifp->if_output = tunoutput; 162 ifp->if_init = tuninit; 163 #ifndef BSD4_3 164 sin = (struct sockaddr_in *) & ifp->if_addr; 165 sin->sin_family = AF_INET; 166 #endif 167 ifp->if_flags = IFF_POINTOPOINT; 168 ifp->if_snd.ifq_maxlen = ifqmaxlen; 169 ifp->if_collisions = ifp->if_ierrors = ifp->if_oerrors = 0; 170 ifp->if_ipackets = ifp->if_opackets = 0; 171 if_attach (ifp); 172 TUNDEBUG ("%s%d: tunattach\n", ifp->if_name, ifp->if_unit); 173 return 0; 174 } 175 176 int 177 tuninit (unit) 178 int unit; 179 { 180 register struct tunctl *tp = &tunctl[unit]; 181 register struct ifnet *ifp = &tp->tun_if; 182 #ifndef BSD4_3 183 register struct sockaddr_in *sin; 184 185 sin = (struct sockaddr_in *) & ifp->if_addr; 186 if (sin->sin_addr.s_addr == 0) /* if address still unknown */ 187 return; 188 if_rtinit (ifp, RTF_UP); 189 #endif 190 ifp->if_flags |= IFF_UP | IFF_RUNNING; 191 tp->tun_flags |= TUN_IASET; 192 TUNDEBUG ("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 193 return 0; 194 } 195 196 /* 197 * Process an ioctl request. 198 * The problem here is 4.2 pass a struct ifreq * to this routine, 199 * sun only passes a struct sockaddr * since 3.2 at least. This is 200 * rather upsetting! Also, sun doesn't pass the SIOCDSTADDR ioctl through 201 * so we can't detect this being set directly. This is the reason for 202 * tuncheckready. 203 * Under 4.3 and SunOs 4.0 we now get the SIOCSIFDSTADDR ioctl, and we get a 204 * struct in_ifaddr * for data. (tte) 205 */ 206 207 #if !defined(BSD4_3) && defined(sun) 208 209 /* 210 * workaround for not being able to detect DSTADDR being set. 211 */ 212 213 tuncheckready (ifp) 214 struct ifnet *ifp; 215 { 216 struct tunctl *tp = &tunctl[ifp->if_unit]; 217 struct sockaddr_in *sin; 218 219 sin = (struct sockaddr_in *) &ifp->if_dstaddr; 220 if (sin->sin_addr.s_addr == 0) 221 return 0; 222 tp -> tun_flags |= TUN_DSTADDR; 223 return 1; 224 } 225 #else 226 #define tuncheckready(dummy) 1 227 #endif /* !defined(BSD4_3) && defined(sun) */ 228 229 int 230 tunioctl (ifp, cmd, data) 231 register struct ifnet *ifp; 232 int cmd; 233 caddr_t data; 234 { 235 #ifndef BSD4_3 236 #ifdef sun 237 struct sockaddr_in *sin = (struct sockaddr_in *) data; 238 #else 239 struct sockaddr_in *sin; 240 struct ifreq *ifr = (struct ifreq *) data; 241 #endif 242 #endif /* BSD4_3 */ 243 244 int s = splimp (), error = 0; 245 struct tunctl *tp = &tunctl[ifp->if_unit]; 246 247 switch (cmd) 248 { 249 case SIOCSIFADDR: 250 #ifndef BSD4_3 251 if (ifp->if_flags & IFF_RUNNING) 252 if_rtinit (ifp, -1); /* delete previous route */ 253 #ifndef sun 254 sin = (struct sockaddr_in *)&ifr -> ifr_addr; 255 #endif 256 ifp->if_addr = *((struct sockaddr *) sin); 257 ifp->if_net = in_netof (sin->sin_addr); 258 ifp->if_host[0] = in_lnaof (sin->sin_addr); 259 #endif 260 tuninit (ifp->if_unit); 261 break; 262 case SIOCSIFDSTADDR: 263 tp->tun_flags |= TUN_DSTADDR; 264 #ifndef BSD4_3 265 #ifndef sun 266 sin = (struct sockaddr_in *)&ifr -> ifr_addr; 267 #endif 268 ifp->if_dstaddr = *((struct sockaddr *)sin); 269 #endif BSD4_3 270 TUNDEBUG ("%s%d: destination addres set\n", ifp->if_name, 271 ifp -> if_unit); 272 break; 273 default: 274 error = EINVAL; 275 } 276 splx (s); 277 return (error); 278 } 279 280 /* 281 * tunoutput - queue packets from higher level ready to put out. 282 */ 283 tunoutput (ifp, m0, dst) 284 struct ifnet *ifp; 285 struct mbuf *m0; 286 struct sockaddr *dst; 287 { 288 struct tunctl *tp; 289 struct proc *p; 290 int s; 291 292 TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); 293 tp = &tunctl[ifp->if_unit]; 294 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 295 if(tuncheckready(ifp) == 0) { 296 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 297 ifp->if_unit, tp->tun_flags); 298 m_freem (m0); 299 return EHOSTDOWN; 300 } 301 } 302 303 switch (dst->sa_family) { 304 #ifdef INET 305 case AF_INET: 306 s = splimp (); 307 if (IF_QFULL (&ifp->if_snd)) 308 { 309 IF_DROP (&ifp->if_snd); 310 m_freem (m0); 311 splx (s); 312 ifp->if_collisions++; 313 return (ENOBUFS); 314 } 315 IF_ENQUEUE (&ifp->if_snd, m0); 316 splx (s); 317 ifp->if_opackets++; 318 break; 319 #endif 320 default: 321 m_freem (m0); 322 return EAFNOSUPPORT; 323 } 324 325 if (tp->tun_flags & TUN_RWAIT) { 326 tp->tun_flags &= ~TUN_RWAIT; 327 wakeup ((caddr_t) tp); 328 } 329 if (tp->tun_flags & TUN_ASYNC && tp -> tun_pgrp != 0) { 330 if (tp->tun_pgrp > 0) 331 gsignal (tp->tun_pgrp, SIGIO); 332 else if ((p = pfind (-tp->tun_pgrp)) != 0) 333 psignal (p, SIGIO); 334 } 335 selwakeup (&tp->tun_rsel); 336 return 0; 337 } 338 339 /* 340 * the cdevsw interface is now pretty minimal. 341 */ 342 343 tuncioctl (dev, cmd, data, flag) 344 dev_t dev; 345 caddr_t data; 346 { 347 int unit = minor(dev); 348 struct tunctl *tp = &tunctl[unit]; 349 int s; 350 351 switch (cmd) { 352 case TUNSDEBUG: 353 tundebug = *(int *)data; 354 break; 355 356 case TUNGDEBUG: 357 *(int *)data = tundebug; 358 break; 359 360 case FIONBIO: 361 if (*(int *)data) 362 tp->tun_flags |= TUN_NBIO; 363 else 364 tp->tun_flags &= ~TUN_NBIO; 365 break; 366 367 case FIOASYNC: 368 if (*(int *)data) 369 tp->tun_flags |= TUN_ASYNC; 370 else 371 tp->tun_flags &= ~TUN_ASYNC; 372 break; 373 374 case FIONREAD: 375 s = splimp (); 376 if (tp->tun_if.if_snd.ifq_head) 377 *(int *)data = tp->tun_if.if_snd.ifq_head->m_len; 378 else *(int *)data = 0; 379 splx (s); 380 break; 381 382 case TIOCSPGRP: 383 tp->tun_pgrp = *(int *)data; 384 break; 385 386 case TIOCGPGRP: 387 *(int *)data = tp->tun_pgrp; 388 break; 389 390 default: 391 return (ENOTTY); 392 } 393 return (0); 394 } 395 396 /* 397 * The cdevsw read interface - reads a packet at a time, or at least as much 398 * of a packet as can be read. 399 */ 400 tunread (dev, uio) 401 dev_t dev; 402 struct uio *uio; 403 { 404 register struct ifnet *ifp; 405 register struct mbuf *m, *m0; 406 int unit = minor (dev); 407 int len, s; 408 int error = 0; 409 struct tunctl *tp; 410 411 tp = &tunctl[unit]; 412 ifp = &tp->tun_if; 413 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit); 414 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 415 if(tuncheckready(ifp) == 0) { 416 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 417 ifp->if_unit, tp->tun_flags); 418 return EHOSTDOWN; 419 } 420 } 421 422 tp->tun_flags &= ~TUN_RWAIT; 423 424 s = splimp (); 425 do { 426 IF_DEQUEUE (&ifp->if_snd, m0); 427 if (m0 == 0) { 428 if (tp -> tun_flags & TUN_NBIO) { 429 splx (s); 430 return EWOULDBLOCK; 431 } 432 tp->tun_flags |= TUN_RWAIT; 433 tsleep ((caddr_t) tp, PZERO + 1, "tunread", 0); 434 } 435 } while (m0 == 0); 436 splx (s); 437 438 while (m0 && uio->uio_resid > 0 && error == 0) { 439 len = MIN (uio->uio_resid, m0->m_len); 440 if (len == 0) 441 break; 442 error = uiomove (mtod (m0, caddr_t), len, 443 UIO_READ, uio); 444 MFREE (m0, m); 445 m0 = m; 446 } 447 448 if (m0 != 0) { 449 TUNDEBUG ("Dropping mbuf\n"); 450 m_freem (m0); 451 } 452 return error; 453 } 454 455 /* 456 * the cdevsw write interface - an atomic write is a packet - or else! 457 */ 458 459 tunwrite (dev, uio) 460 int dev; 461 struct uio *uio; 462 { 463 int error = 0; 464 int unit = minor (dev); 465 struct mbuf *top, **mp, *m; 466 struct ifnet *ifp = &(tunctl[unit].tun_if); 467 int s; 468 469 TUNDEBUG ("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit); 470 471 if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) { 472 TUNDEBUG ("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit, 473 uio->uio_resid); 474 return EIO; 475 } 476 top = 0; 477 mp = ⊤ 478 while (error == 0 && uio->uio_resid > 0) { 479 MGET (m, M_DONTWAIT, MT_DATA); 480 if (m == 0) { 481 error = ENOBUFS; 482 break; 483 } 484 m->m_len = MIN (MLEN, uio->uio_resid); 485 error = uiomove (mtod (m, caddr_t), m->m_len, UIO_WRITE, uio); 486 *mp = m; 487 mp = &m->m_next; 488 } 489 if (error) { 490 if (top) 491 m_freem (top); 492 return error; 493 } 494 495 #ifdef BSD4_3 496 /* 497 * Place interface pointer before the data 498 * for the receiving protocol. 499 */ 500 if (top->m_off <= MMAXOFF && 501 top->m_off >= MMINOFF + sizeof(struct ifnet *)) { 502 top->m_off -= sizeof(struct ifnet *); 503 top->m_len += sizeof(struct ifnet *); 504 } else { 505 MGET(m, M_DONTWAIT, MT_HEADER); 506 if (m == (struct mbuf *)0) 507 return (ENOBUFS); 508 m->m_len = sizeof(struct ifnet *); 509 m->m_next = top; 510 top = m; 511 } 512 *(mtod(top, struct ifnet **)) = ifp; 513 #endif /* BSD4_3 */ 514 515 s = splimp (); 516 if (IF_QFULL (&ipintrq)) { 517 IF_DROP (&ipintrq); 518 splx (s); 519 ifp->if_collisions++; 520 m_freem (top); 521 return ENOBUFS; 522 } 523 IF_ENQUEUE (&ipintrq, top); 524 splx (s); 525 ifp->if_ipackets++; 526 schednetisr (NETISR_IP); 527 return error; 528 } 529 530 /* 531 * tunselect - the select interface, this is only useful on reads really. 532 * The write detect always returns true, write never blocks anyway, it either 533 * accepts the packet or drops it. 534 */ 535 tunselect (dev, rw) 536 dev_t dev; 537 int rw; 538 { 539 int unit = minor (dev); 540 register struct tunctl *tp = &tunctl[unit]; 541 struct ifnet *ifp = &tp->tun_if; 542 int s = splimp (); 543 544 TUNDEBUG ("%s%d: tunselect\n", ifp->if_name, ifp->if_unit); 545 switch (rw) { 546 case FREAD: 547 if (ifp->if_snd.ifq_len > 0) { 548 splx (s); 549 TUNDEBUG ("%s%d: tunselect q=%d\n", ifp->if_name, 550 ifp->if_unit, ifp->if_snd.ifq_len); 551 return 1; 552 } 553 selrecord(p, &tp->tun_rsel); 554 break; 555 case FWRITE: 556 splx (s); 557 return 1; 558 } 559 splx (s); 560 TUNDEBUG ("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit); 561 return 0; 562 } 563 #endif NTUN 564