fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 137 lines 3.0 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/lib/tun.c * 7 * Created: 2004-12-15 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2018 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include <config.h> 24 25#include <lib/tun.h> 26 27#include <string.h> 28#include <unistd.h> 29 30#include <sys/ioctl.h> 31#include <sys/fcntl.h> 32#include <sys/types.h> 33#include <sys/poll.h> 34#include <sys/socket.h> 35 36#include <linux/if.h> 37#include <linux/if_tun.h> 38 39 40/* 41 * Flags: IFF_TUN - TUN device (no Ethernet headers) 42 * IFF_TAP - TAP device 43 * 44 * IFF_NO_PI - Do not provide packet information 45 */ 46 47static 48int tuntap_open (const char *name, int tap) 49{ 50 int fd; 51 struct ifreq req; 52 53 fd = open ("/dev/net/tun", O_RDWR); 54 55 if (fd < 0) { 56 return (-1); 57 } 58 59 memset (&req, 0, sizeof (req)); 60 61 req.ifr_flags = (tap ? IFF_TAP : IFF_TUN) | IFF_NO_PI; 62 strncpy (req.ifr_name, name, IFNAMSIZ - 1); 63 64 if (ioctl (fd, TUNSETIFF, (void *) &req) < 0) { 65 close (fd); 66 return (-1); 67 } 68 69 return (fd); 70} 71 72int tun_open (const char *name) 73{ 74 return (tuntap_open (name, 0)); 75} 76 77int tap_open (const char *name) 78{ 79 return (tuntap_open (name, 1)); 80} 81 82void tun_close (int fd) 83{ 84 close (fd); 85} 86 87int tun_set_packet (int fd, const void *buf, unsigned cnt) 88{ 89 ssize_t r; 90 91 r = write (fd, buf, cnt); 92 93 if (r < 0) { 94 return (1); 95 } 96 97 if ((unsigned) r != cnt) { 98 return (1); 99 } 100 101 return (0); 102} 103 104int tun_get_packet (int fd, void *buf, unsigned *cnt) 105{ 106 ssize_t r; 107 108 r = read (fd, buf, *cnt); 109 if (r < 0) { 110 return (1); 111 } 112 113 *cnt = (unsigned) r; 114 115 return (0); 116} 117 118int tun_check_packet (int fd) 119{ 120 int r; 121 struct pollfd pfd[1]; 122 123 pfd[0].fd = fd; 124 pfd[0].events = POLLIN; 125 126 r = poll (pfd, 1, 0); 127 if (r < 0) { 128 return (0); 129 } 130 131 if ((pfd[0].revents & POLLIN) == 0) { 132 return (0); 133 } 134 135 return (1); 136} 137