Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

tun-solaris.c

Go to the documentation of this file.
00001 /*
00002  * tun-solaris.c
00003  *
00004  * Universal TUN/TAP driver
00005  *
00006  * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
00007  *
00008  * $Id: tun-solaris.c,v 1.2 2005/01/25 21:30:40 dugsong Exp $
00009  */
00010 
00011 #include "config.h"
00012 
00013 #include <sys/ioctl.h>
00014 #include <sys/socket.h>
00015 #include <sys/sockio.h>
00016 
00017 #include <net/if.h>
00018 #include <net/if_tun.h>
00019 
00020 #include <fcntl.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <stropts.h>
00025 #include <unistd.h>
00026 
00027 #include "dnet.h"
00028 
00029 #define DEV_TUN         "/dev/tun"
00030 #define DEV_IP          "/dev/ip"
00031 
00032 struct tun {
00033         int              fd;
00034         int              ip_fd;
00035         int              if_fd;
00036         char             name[16];
00037 };
00038 
00039 tun_t *
00040 tun_open(struct addr *src, struct addr *dst, int mtu)
00041 {
00042         tun_t *tun;
00043         char cmd[512];
00044         int ppa;
00045 
00046         if ((tun = calloc(1, sizeof(*tun))) == NULL)
00047                 return (NULL);
00048 
00049         tun->fd = tun->ip_fd = tun->if_fd = -1;
00050         
00051         if ((tun->fd = open(DEV_TUN, O_RDWR, 0)) < 0)
00052                 return (tun_close(tun));
00053 
00054         if ((tun->ip_fd = open(DEV_IP, O_RDWR, 0)) < 0)
00055                 return (tun_close(tun));
00056         
00057         if ((ppa = ioctl(tun->fd, TUNNEWPPA, ppa)) < 0)
00058                 return (tun_close(tun));
00059 
00060         if ((tun->if_fd = open(DEV_TUN, O_RDWR, 0)) < 0)
00061                 return (tun_close(tun));
00062 
00063         if (ioctl(tun->if_fd, I_PUSH, "ip") < 0)
00064                 return (tun_close(tun));
00065         
00066         if (ioctl(tun->if_fd, IF_UNITSEL, (char *)&ppa) < 0)
00067                 return (tun_close(tun));
00068 
00069         if (ioctl(tun->ip_fd, I_LINK, tun->if_fd) < 0)
00070                 return (tun_close(tun));
00071 
00072         snprintf(tun->name, sizeof(tun->name), "tun%d", ppa);
00073         
00074         snprintf(cmd, sizeof(cmd), "ifconfig %s %s/32 %s mtu %d up",
00075             tun->name, addr_ntoa(src), addr_ntoa(dst), mtu);
00076         
00077         if (system(cmd) < 0)
00078                 return (tun_close(tun));
00079         
00080         return (tun);
00081 }
00082 
00083 const char *
00084 tun_name(tun_t *tun)
00085 {
00086         return (tun->name);
00087 }
00088 
00089 int
00090 tun_fileno(tun_t *tun)
00091 {
00092         return (tun->fd);
00093 }
00094 
00095 ssize_t
00096 tun_send(tun_t *tun, const void *buf, size_t size)
00097 {
00098         struct strbuf sbuf;
00099 
00100         sbuf.buf = buf;
00101         sbuf.len = size;
00102         return (putmsg(tun->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1);
00103 }
00104 
00105 ssize_t
00106 tun_recv(tun_t *tun, void *buf, size_t size)
00107 {
00108         struct strbuf sbuf;
00109         int flags = 0;
00110         
00111         sbuf.buf = buf;
00112         sbuf.maxlen = size;
00113         return (getmsg(tun->fd, NULL, &sbuf, &flags) >= 0 ? sbuf.len : -1);
00114 }
00115 
00116 tun_t *
00117 tun_close(tun_t *tun)
00118 {
00119         if (tun->if_fd >= 0)
00120                 close(tun->if_fd);
00121         if (tun->ip_fd >= 0)
00122                 close(tun->ip_fd);
00123         if (tun->fd >= 0)
00124                 close(tun->fd);
00125         free(tun);
00126         return (NULL);
00127 }

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2