Annotation of qemu/net/tap-solaris.c, revision 1.1
1.1 ! root 1: /*
! 2: * QEMU System Emulator
! 3: *
! 4: * Copyright (c) 2003-2008 Fabrice Bellard
! 5: *
! 6: * Permission is hereby granted, free of charge, to any person obtaining a copy
! 7: * of this software and associated documentation files (the "Software"), to deal
! 8: * in the Software without restriction, including without limitation the rights
! 9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! 10: * copies of the Software, and to permit persons to whom the Software is
! 11: * furnished to do so, subject to the following conditions:
! 12: *
! 13: * The above copyright notice and this permission notice shall be included in
! 14: * all copies or substantial portions of the Software.
! 15: *
! 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! 17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
! 19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! 21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! 22: * THE SOFTWARE.
! 23: */
! 24:
! 25: #include "net/tap.h"
! 26:
! 27: #include <sys/stat.h>
! 28: #include <sys/ethernet.h>
! 29: #include <sys/sockio.h>
! 30: #include <netinet/arp.h>
! 31: #include <netinet/in.h>
! 32: #include <netinet/in_systm.h>
! 33: #include <netinet/ip.h>
! 34: #include <netinet/ip_icmp.h> // must come after ip.h
! 35: #include <netinet/udp.h>
! 36: #include <netinet/tcp.h>
! 37: #include <net/if.h>
! 38: #include <syslog.h>
! 39: #include <stropts.h>
! 40:
! 41: ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
! 42: {
! 43: struct strbuf sbuf;
! 44: int f = 0;
! 45:
! 46: sbuf.maxlen = maxlen;
! 47: sbuf.buf = (char *)buf;
! 48:
! 49: return getmsg(tapfd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
! 50: }
! 51:
! 52: #define TUNNEWPPA (('T'<<16) | 0x0001)
! 53: /*
! 54: * Allocate TAP device, returns opened fd.
! 55: * Stores dev name in the first arg(must be large enough).
! 56: */
! 57: static int tap_alloc(char *dev, size_t dev_size)
! 58: {
! 59: int tap_fd, if_fd, ppa = -1;
! 60: static int ip_fd = 0;
! 61: char *ptr;
! 62:
! 63: static int arp_fd = 0;
! 64: int ip_muxid, arp_muxid;
! 65: struct strioctl strioc_if, strioc_ppa;
! 66: int link_type = I_PLINK;;
! 67: struct lifreq ifr;
! 68: char actual_name[32] = "";
! 69:
! 70: memset(&ifr, 0x0, sizeof(ifr));
! 71:
! 72: if( *dev ){
! 73: ptr = dev;
! 74: while( *ptr && !qemu_isdigit((int)*ptr) ) ptr++;
! 75: ppa = atoi(ptr);
! 76: }
! 77:
! 78: /* Check if IP device was opened */
! 79: if( ip_fd )
! 80: close(ip_fd);
! 81:
! 82: TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
! 83: if (ip_fd < 0) {
! 84: syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
! 85: return -1;
! 86: }
! 87:
! 88: TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
! 89: if (tap_fd < 0) {
! 90: syslog(LOG_ERR, "Can't open /dev/tap");
! 91: return -1;
! 92: }
! 93:
! 94: /* Assign a new PPA and get its unit number. */
! 95: strioc_ppa.ic_cmd = TUNNEWPPA;
! 96: strioc_ppa.ic_timout = 0;
! 97: strioc_ppa.ic_len = sizeof(ppa);
! 98: strioc_ppa.ic_dp = (char *)&ppa;
! 99: if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
! 100: syslog (LOG_ERR, "Can't assign new interface");
! 101:
! 102: TFR(if_fd = open("/dev/tap", O_RDWR, 0));
! 103: if (if_fd < 0) {
! 104: syslog(LOG_ERR, "Can't open /dev/tap (2)");
! 105: return -1;
! 106: }
! 107: if(ioctl(if_fd, I_PUSH, "ip") < 0){
! 108: syslog(LOG_ERR, "Can't push IP module");
! 109: return -1;
! 110: }
! 111:
! 112: if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
! 113: syslog(LOG_ERR, "Can't get flags\n");
! 114:
! 115: snprintf (actual_name, 32, "tap%d", ppa);
! 116: pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
! 117:
! 118: ifr.lifr_ppa = ppa;
! 119: /* Assign ppa according to the unit number returned by tun device */
! 120:
! 121: if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
! 122: syslog (LOG_ERR, "Can't set PPA %d", ppa);
! 123: if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
! 124: syslog (LOG_ERR, "Can't get flags\n");
! 125: /* Push arp module to if_fd */
! 126: if (ioctl (if_fd, I_PUSH, "arp") < 0)
! 127: syslog (LOG_ERR, "Can't push ARP module (2)");
! 128:
! 129: /* Push arp module to ip_fd */
! 130: if (ioctl (ip_fd, I_POP, NULL) < 0)
! 131: syslog (LOG_ERR, "I_POP failed\n");
! 132: if (ioctl (ip_fd, I_PUSH, "arp") < 0)
! 133: syslog (LOG_ERR, "Can't push ARP module (3)\n");
! 134: /* Open arp_fd */
! 135: TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
! 136: if (arp_fd < 0)
! 137: syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
! 138:
! 139: /* Set ifname to arp */
! 140: strioc_if.ic_cmd = SIOCSLIFNAME;
! 141: strioc_if.ic_timout = 0;
! 142: strioc_if.ic_len = sizeof(ifr);
! 143: strioc_if.ic_dp = (char *)𝔦
! 144: if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
! 145: syslog (LOG_ERR, "Can't set ifname to arp\n");
! 146: }
! 147:
! 148: if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
! 149: syslog(LOG_ERR, "Can't link TAP device to IP");
! 150: return -1;
! 151: }
! 152:
! 153: if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
! 154: syslog (LOG_ERR, "Can't link TAP device to ARP");
! 155:
! 156: close (if_fd);
! 157:
! 158: memset(&ifr, 0x0, sizeof(ifr));
! 159: pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
! 160: ifr.lifr_ip_muxid = ip_muxid;
! 161: ifr.lifr_arp_muxid = arp_muxid;
! 162:
! 163: if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
! 164: {
! 165: ioctl (ip_fd, I_PUNLINK , arp_muxid);
! 166: ioctl (ip_fd, I_PUNLINK, ip_muxid);
! 167: syslog (LOG_ERR, "Can't set multiplexor id");
! 168: }
! 169:
! 170: snprintf(dev, dev_size, "tap%d", ppa);
! 171: return tap_fd;
! 172: }
! 173:
! 174: int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required)
! 175: {
! 176: char dev[10]="";
! 177: int fd;
! 178: if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
! 179: fprintf(stderr, "Cannot allocate TAP device\n");
! 180: return -1;
! 181: }
! 182: pstrcpy(ifname, ifname_size, dev);
! 183: if (*vnet_hdr) {
! 184: /* Solaris doesn't have IFF_VNET_HDR */
! 185: *vnet_hdr = 0;
! 186:
! 187: if (vnet_hdr_required && !*vnet_hdr) {
! 188: qemu_error("vnet_hdr=1 requested, but no kernel "
! 189: "support for IFF_VNET_HDR available");
! 190: close(fd);
! 191: return -1;
! 192: }
! 193: }
! 194: fcntl(fd, F_SETFL, O_NONBLOCK);
! 195: return fd;
! 196: }
! 197:
! 198: int tap_set_sndbuf(int fd, QemuOpts *opts)
! 199: {
! 200: return 0;
! 201: }
! 202:
! 203: int tap_probe_vnet_hdr(int fd)
! 204: {
! 205: return 0;
! 206: }
! 207:
! 208: int tap_probe_has_ufo(int fd)
! 209: {
! 210: return 0;
! 211: }
! 212:
! 213: void tap_fd_set_offload(int fd, int csum, int tso4,
! 214: int tso6, int ecn, int ufo)
! 215: {
! 216: }
unix.superglobalmegacorp.com