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