Merge pull request #74 from digarok/ks-master

Ks master
This commit is contained in:
Dagen Brock 2019-05-11 10:18:29 -05:00 committed by GitHub
commit 9d44843aab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
125 changed files with 21143 additions and 4456 deletions

View File

@ -12,10 +12,13 @@ build-ubuntu-x:
- ubuntu
stage: build
script:
- sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libxext-dev
- cd src
- ln -s vars_x86linux_x11 vars
- sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libxext-dev re2c cmake
- mkdir build
- cd build
- cmake ..
- make
- make clean ; make
- mv bin/GSplus ../gsplusx
artifacts:
paths:
- gsplusx
@ -62,11 +65,12 @@ build-ubuntu-sdl2:
- ubuntu
stage: build
script:
- sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libsdl2-dev libfreetype6-dev libsdl2-image-dev
- cd src
- ln -s vars_x86linux_sdl2 vars
- make clean ; make
- mv ../gsplus ../gsplus-ubuntu-sdl.bin
- sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libsdl2-dev libfreetype6-dev libsdl2-image-dev re2c cmake
- mkdir build
- cd build
- cmake ..
- make
- mv bin/GSplus ../gsplus-ubuntu-sdl.bin
artifacts:
paths:
- gsplus-ubuntu-sdl.bin
@ -126,22 +130,22 @@ deploy-ubuntu:
- aws s3 cp $PACKAGE_NAME.deb s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/ubuntu-sdl-deb/$CI_BUILD_ID/ --acl public-read
# TARGET SYSTEM: OSX 10.SOMETHING
build-osx:
tags:
- osx
stage: build
script:
- cd src
- ln -s vars_osx_sdl2 vars
- mkdir build
- cd build
- cmake ..
- make
- make clean ; make
- mv ../gsplus ../gsplus-osx
- mv bin/GSplus.app/Contents/MacOS/GSplus ../gsplus-osx
artifacts:
paths:
- gsplus-osx
expire_in: 10 minutes
expire_in: 15 minutes
package-osx:
tags:
@ -170,123 +174,139 @@ deploy-osx:
- aws s3 cp GSplus-Install.dmg s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/osx/$CI_BUILD_ID/ --acl public-read
# TARGET SYSTEM: WIN32 WIN API UNDER CYGWIN
build-win32:
# TARGET SYSTEM: WIN32 GDI WIN API UNDER MSYS2
build-win32-gdi:
tags:
- windows
- windows,msys
stage: build
script:
- bash -c "cd src; ln -s vars_win32 vars; make clean ; make"
- ls
- mkdir build
- cd build
- cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "Unix Makefiles"
- make VERBOSE=1 GSplus
- mv bin/GSplus.exe ../GSplus-win32-gdi.exe
artifacts:
paths:
- gsplus32.exe
- GSplus-win32-gdi.exe
expire_in: 10 minutes
only:
- master
- /^win.*/
- /^ks.*/
package-win32:
package-win32-gdi:
tags:
- windows
- windows,msys
variables:
GIT_STRATEGY: fetch
PACKAGE_DIR: gsplus-win32-gdi
stage: package
script:
- cp src/config.txt .
- 'echo "# CI_BUILD_ID: $CI_BUILD_ID" >> config.txt'
- ls
- mkdir %PACKAGE_DIR%
- cp src/config.txt %PACKAGE_DIR%
- 'echo "# CI_BUILD_ID: $CI_BUILD_ID" >> %PACKAGE_DIR%/config.txt'
- cp LICENSE.txt doc/
- cp /bin/cyggcc_s-1.dll .
- cp /bin/cygstdc++-6.dll .
- cp /bin/cygwin1.dll .
- cp /bin/cygfreetype-6.dll .
variables:
GIT_STRATEGY: fetch
PACKAGE_DIR: gsplus-win32
script:
- mkdir %PACKAGE_DIR%
- cp gsplus32.exe %PACKAGE_DIR%
- cp GSplus-win32-gdi.exe %PACKAGE_DIR%/GSplus.exe
- cp LICENSE.txt %PACKAGE_DIR%
- cp src/config.txt %PACKAGE_DIR%
- cp src/parallel.rom %PACKAGE_DIR%
- cp doc/gsplusmanual.pdf %PACKAGE_DIR%
- cp doc/README.txt %PACKAGE_DIR%
- cp /bin/cyggcc_s-1.dll %PACKAGE_DIR%
- cp /bin/cygstdc++-6.dll %PACKAGE_DIR%
- cp /bin/cygwin1.dll %PACKAGE_DIR%
- cp /bin/cygfreetype-6.dll %PACKAGE_DIR%
- zip gsplus-win32.zip -r %PACKAGE_DIR%
- cp /mingw32/bin/libgcc_s_dw2-1.dll %PACKAGE_DIR%
- cp /mingw32/bin/libstdc++-6.dll %PACKAGE_DIR%
- cp /mingw32/bin/libwinpthread-1.dll %PACKAGE_DIR%
- zip gsplus-win32-gdi.zip -r %PACKAGE_DIR%
artifacts:
paths:
- gsplus-win32.zip
- gsplus-win32-gdi.zip
expire_in: 10 minutes
only:
- master
- /^win.*/
- /^ks.*/
deploy-win32:
deploy-win32-gdi:
tags:
- windows
- osx
stage: deploy
variables:
GIT_STRATEGY: none
script:
- aws s3 cp gsplus-win32.zip s3://%AWS_BUCKET%/%CI_TAG%/%CI_VERSION%/%CI_PIPELINE_ID%/win32/%CI_BUILD_ID%/ --acl public-read
- aws s3 cp gsplus-win32-gdi.zip s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/win32/$CI_BUILD_ID/ --acl public-read
only:
- master
- /^win.*/
- /^ks.*/
# TARGET SYSTEM: WIN32 SDL2 UNDER CYGWIN W MINGW64 SDL2 LIBS
build-win-sdl2:
# TARGET SYSTEM: MSYS2 MINGW32 SDL2
build-win32-sdl2:
tags:
- windows
stage: build
script:
- cd src
- ln -s vars_win32_sdl2 vars
- make clean
- make
- mkdir build
- cd build
- bash -l -c 'PATH=/mingw32/bin:$PATH ; MSYSTEM=MINGW32 MSYSTEM_PREFIX=/mingw32 /mingw32/bin/cmake ../ -DDRIVER=SDL2 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles"'
- bash -l -c 'PATH=/mingw32/bin:$PATH ;MSYSTEM=MINGW32 MSYSTEM_PREFIX=/mingw32 /mingw32/bin/mingw32-make VERBOSE=1 GSplus'
- mv bin/GSplus.exe ../GSplus-win32-sdl.exe
artifacts:
paths:
- gsplus.exe
- GSplus-win32-sdl.exe
expire_in: 10 minutes
only:
- master
- /^win.*/
- /^ks.*/
package-win-sdl2:
package-win32-sdl2:
tags:
- windows
stage: package
variables:
GIT_STRATEGY: fetch
PACKAGE_DIR: gsplus-win-sdl
PACKAGE_DIR: gsplus-win32-sdl
script:
- ls
- mkdir %PACKAGE_DIR%
- cp gsplus.exe %PACKAGE_DIR%
- cp GSplus-win32-sdl.exe %PACKAGE_DIR%/GSplus.exe
- cp LICENSE.txt %PACKAGE_DIR%
- cp src/config.txt %PACKAGE_DIR%
- cp src/parallel.rom %PACKAGE_DIR%
- cp doc/gsplusmanual.pdf %PACKAGE_DIR%
- cp doc/README.txt %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygbz2-1.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygfreetype-6.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cyggcc_s-1.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygjpeg-8.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygpng16-16.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygjpeg-8.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygstdc++-6.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygwin1.dll %PACKAGE_DIR%
- cp /cygdrive/c/cygwin/bin/cygz.dll %PACKAGE_DIR%
- cp /cygdrive/c/mingw/i686-w64-mingw32/bin/SDL2.dll %PACKAGE_DIR%
- cp /cygdrive/c/mingw/i686-w64-mingw32/bin/SDL2_image.dll %PACKAGE_DIR%
- zip gsplus-win-sdl.zip -r %PACKAGE_DIR%
- cp /mingw32/bin/libbz2-1.dll %PACKAGE_DIR%
- cp /mingw32/bin/libfreetype-6.dll %PACKAGE_DIR%
- cp /mingw32/bin/libgcc_s_dw2-1.dll %PACKAGE_DIR%
- cp /mingw32/bin/libglib-2.0-0.dll %PACKAGE_DIR%
- cp /mingw32/bin/libgraphite2.dll %PACKAGE_DIR%
- cp /mingw32/bin/libharfbuzz-0.dll %PACKAGE_DIR%
- cp /mingw32/bin/libiconv-2.dll %PACKAGE_DIR%
- cp /mingw32/bin/libintl-8.dll %PACKAGE_DIR%
- cp /mingw32/bin/libpcre-1.dll %PACKAGE_DIR%
- cp /mingw32/bin/libpng16-16.dll %PACKAGE_DIR%
- cp /mingw32/bin/libstdc++-6.dll %PACKAGE_DIR%
- cp /mingw32/bin/libwinpthread-1.dll %PACKAGE_DIR%
- cp /mingw32/bin/SDL2.dll %PACKAGE_DIR%
- cp /mingw32/bin/SDL2_image.dll %PACKAGE_DIR%
- cp /mingw32/bin/zlib1.dll %PACKAGE_DIR%
- zip gsplus-win32-sdl.zip -r %PACKAGE_DIR%
artifacts:
paths:
- gsplus-win-sdl.zip
- gsplus-win32-sdl.zip
expire_in: 10 minutes
deploy-win-sdl2:
deploy-win32-sdl2:
tags:
- windows
- osx
stage: deploy
variables:
GIT_STRATEGY: none
script:
- aws s3 cp gsplus-win-sdl.zip s3://%AWS_BUCKET%/%CI_TAG%/%CI_VERSION%/%CI_PIPELINE_ID%/win-sdl/%CI_BUILD_ID%/ --acl public-read
- aws s3 cp gsplus-win32-sdl.zip s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/win-sdl/$CI_BUILD_ID/ --acl public-read
update-website-universal:
tags:
@ -299,4 +319,3 @@ update-website-universal:
- php assets/updatewebsite.php s3artifacts.txt public > index.html
- php assets/updatewebsite.php s3artifacts.txt auto > index_auto.html
- aws s3 cp index.html s3://$AWS_BUCKET/ --acl public-read
- aws s3 cp index_auto.html s3://$AWS_BUCKET/ --acl public-read

28
.travis.yml Normal file
View File

@ -0,0 +1,28 @@
language: c
matrix:
include:
- os: linux
dist: xenial
- os: osx
addons:
apt:
packages:
- re2c
- libsdl2-dev
- libsdl2-image-dev
- libfreetype6-dev
homebrew:
packages:
- re2c
- sdl2
- sdl2_image
- freetype
before_script:
- mkdir build
- cd build
- cmake ..
script: make GSplus

23
CMakeLists.txt Normal file
View File

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.1)
project(gsplus VERSION 0.14)
if(CYGWIN OR MSYS)
set(WIN32 1)
add_definitions(-DWIN32 -D_WIN32 -D__USE_W32_SOCKETS)
endif()
# msys/cygwin/mingw32 add dirent.h, etc.
# Visual C++ does not.
if(MSVC)
include_directories(include/msvc)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_compile_options(/wd4996)
endif()
# add pcap headers for win32. assume os/x, linux, etc, already have them.
if(WIN32)
include_directories(include/npcap)
endif()
add_subdirectory(src bin)

View File

@ -1,22 +1,45 @@
# GSplus
An Apple IIgs emulator for Mac OSX, Windows, and Linux.
# GS+ Pro Xtreme HD Developer Edition
![Screenshot of starting the program](doc/web/Screenshot.png "Screenshot of starting the program")
My personal fork of GSplus which is a fork of GSport which is fork of KEGS. Replaces the edbugger facilities with something more suitable for my tastes.
# About
This is an early release of an experimental project to modernize the
KEGS/GSport emulator platform and eventually extend it.
# Build instructions
# Install
Go to https://apple2.gs/plus to get the latest downloads for your system.
## OS X dependencies
brew install re2c sdl2 sdl2_image freetype
# Usage Notes
You need to provide the ROM file and disk images and a config file. I'd
recommend you just drop it in your current GSport or KEGS folder and run it
from there.
## Linux dependencies
apt-get install re2c libsdl2-dev libsdl2-image-dev libfreetype6-dev libpcap0.8-dev
See the doc/gsplusmanual.pdf file for much more complete documentation.
## WIN32 dependencies
Install MSYS2 (not MSYS, not cygwin)
# Build Instructions
See the /doc/ directory for "Developer-Quickstart" docs which cover building
for the various platforms.
32-bit build:
pacman -S re2c mingw-w64-i686-cmake mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_image mingw-w64-i686-freetype
64-bit build:
pacman -S re2c mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_image mingw-w64-x86_64-freetype
## Linux, OS X, build
mkdir build
cd build
cmake ..
(optionally: ccmake .. to configure stuff)
make
## Windows Build
### mingw SDL build
mkdir build
cd build
cmake ../ -DDRIVER=SDL2 -DWITH_DEBUGGER=OFF -G "MSYS Makefiles"
make GSplus.exe
### mingw GDI build
mkdir build
cd build
cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -G "MSYS Makefiles"
make GSplus.exe

141
appveyor.yml Normal file
View File

@ -0,0 +1,141 @@
version: 1.0.{build}
image:
- Visual Studio 2017
- Ubuntu1804
configuration:
- mingw32-sdl
- mingw32-gdi
- mingw64-gdi
- msys-gdi
- linux-sdl
- linux-headless
matrix:
exclude:
- configuration: linux-sdl
image: Visual Studio 2017
- configuration: linux-headless
image: Visual Studio 2017
- configuration: mingw32-sdl
image: Ubuntu1804
- configuration: mingw32-gdi
image: Ubuntu1804
- configuration: mingw64-gdi
image: Ubuntu1804
- configuration: msys-gdi
image: Ubuntu1804
for:
- # mingw64/gdi
matrix:
only:
- image: Visual Studio 2017
configuration: mingw64-gdi
install:
- cmd: set MSYSTEM=MINGW64
- cmd: set MSYSTEM_PREFIX=/mingw64
- cmd: set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%
- cmd: pacman --noconfirm -Sy
- cmd: pacman --noconfirm -S re2c mingw-w64-x86_64-cmake
build_script:
- cmd: mkdir build
- cmd: cd build
- cmd: cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles"
- cmd: make VERBOSE=1 GSplus
artifacts:
- path: 'build\bin\GSplus.exe'
name: GSplus-64-gdi
- # mingw32/gdi
matrix:
only:
- image: Visual Studio 2017
configuration: mingw32-gdi
install:
- cmd: set MSYSTEM=MINGW32
- cmd: set MSYSTEM_PREFIX=/mingw32
- cmd: set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\bin;%PATH%
- cmd: pacman --noconfirm -Sy
- cmd: pacman --noconfirm -S re2c mingw-w64-i686-cmake
build_script:
- cmd: mkdir build
- cmd: cd build
- cmd: cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles"
- cmd: make VERBOSE=1 GSplus
artifacts:
- path: 'build\bin\GSplus.exe'
name: GSplus-32-gdi
- # mingw32/sdl
matrix:
only:
- image: Visual Studio 2017
configuration: mingw32-sdl
install:
- cmd: set MSYSTEM=MINGW32
- cmd: set MSYSTEM_PREFIX=/mingw32
- cmd: set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\bin;%PATH%
- cmd: pacman --noconfirm -Sy
- cmd: pacman --noconfirm -S re2c mingw-w64-i686-cmake mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_image mingw-w64-i686-freetype
build_script:
- cmd: mkdir build
- cmd: cd build
- cmd: cmake ../ -DDRIVER=SDL2 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles"
- cmd: make VERBOSE=1 GSplus
artifacts:
- path: 'build\bin\GSplus.exe'
name: GSplus-32-sdl
- # msys2/gdi
matrix:
only:
- image: Visual Studio 2017
configuration: msys-gdi
install:
- cmd: set MSYSTEM=MSYS
- cmd: set MSYSTEM_PREFIX=/usr/
- cmd: set PATH=C:\msys64\bin;C:\msys64\usr\bin;%PATH%
- cmd: pacman --noconfirm -Sy
- cmd: pacman --noconfirm -S re2c
build_script:
- cmd: mkdir build
- cmd: cd build
- cmd: cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "Unix Makefiles"
- cmd: make VERBOSE=1 GSplus
artifacts:
- path: 'build\bin\GSplus.exe'
name: GSplus-cygwin-32-gdi
- # linux/sdl
matrix:
only:
- image: Ubuntu1804
configuration: linux-sdl
install:
- sh: sudo apt-get update
- sh: sudo apt-get install -y re2c libsdl2-dev libsdl2-image-dev libfreetype6-dev
build_script:
- sh: mkdir build
- sh: cd build
- sh: cmake ../ -DDRIVER=SDL2
- sh: make VERBOSE=1 GSplus
artifacts:
- path: 'build/bin/GSplus'
name: GSplus-linux-sdl
- # linux/headless
matrix:
only:
- image: Ubuntu1804
configuration: linux-headless
install:
- sh: sudo apt-get update
- sh: sudo apt-get install -y re2c
build_script:
- sh: mkdir build
- sh: cd build
- sh: cmake ../ -DDRIVER=HEADLESS
- sh: make VERBOSE=1 GSplus
artifacts:
- path: 'build/bin/GSplus'
name: GSplus-linux-headless

View File

@ -6,11 +6,10 @@
# relatively straightforward to modify for something like yum
# system prep
# Build tools
sudo apt-get -y update
sudo apt-get -y upgrade
sudo apt-get -y install git
sudo apt-get -y install g++
sudo apt-get -y install git g++ cmake re2c
sudo apt-get -y install libpcap0.8-dev
sudo apt-get -y install libfreetype6-dev
@ -27,8 +26,9 @@ sudo apt-get -y install libsdl2-dev
sudo apt-get -y install libsdl2-image-dev
# Example build to test out our system
cd gsplus/src
ln -s vars_x86linux_sdl2 vars
make clean ; make
# Clone & Build.
git clone git@github.com:digarok/gsplus.git
mkdir build ; cd build
cmake ..
make

View File

@ -14,12 +14,10 @@ xcode-select --install
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
# Use brew to install dependencies.
brew install sdl2
brew install sdl2_image
brew install freetype
brew install sdl2 sdl2_image freetype re2c cmake
# Build.
# Clone & Build.
git clone git@github.com:digarok/gsplus.git
cd gsplus/src
ln -s vars_osx_sdl2 vars
make clean ; make
mkdir build ; cd build
cmake ..
make

421
include/npcap/Packet32.h Normal file
View File

@ -0,0 +1,421 @@
/***********************IMPORTANT NPCAP LICENSE TERMS***********************
* *
* Npcap is a Windows packet sniffing driver and library and is copyright *
* (c) 2013-2016 by Insecure.Com LLC ("The Nmap Project"). All rights *
* reserved. *
* *
* Even though Npcap source code is publicly available for review, it is *
* not open source software and my not be redistributed or incorporated *
* into other software without special permission from the Nmap Project. *
* We fund the Npcap project by selling a commercial license which allows *
* companies to redistribute Npcap with their products and also provides *
* for support, warranty, and indemnification rights. For details on *
* obtaining such a license, please contact: *
* *
* sales@nmap.com *
* *
* Free and open source software producers are also welcome to contact us *
* for redistribution requests. However, we normally recommend that such *
* authors instead ask your users to download and install Npcap *
* themselves. *
* *
* Since the Npcap source code is available for download and review, *
* users sometimes contribute code patches to fix bugs or add new *
* features. By sending these changes to the Nmap Project (including *
* through direct email or our mailing lists or submitting pull requests *
* through our source code repository), it is understood unless you *
* specify otherwise that you are offering the Nmap Project the *
* unlimited, non-exclusive right to reuse, modify, and relicence your *
* code contribution so that we may (but are not obligated to) *
* incorporate it into Npcap. If you wish to specify special license *
* conditions or restrictions on your contributions, just say so when you *
* send them. *
* *
* This software is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* Other copyright notices and attribution may appear below this license *
* header. We have kept those for attribution purposes, but any license *
* terms granted by those notices apply only to their original work, and *
* not to any changes made by the Nmap Project or to this entire file. *
* *
* This header summarizes a few important aspects of the Npcap license, *
* but is not a substitute for the full Npcap license agreement, which is *
* in the LICENSE file included with Npcap and also available at *
* https://github.com/nmap/npcap/blob/master/LICENSE. *
* *
***************************************************************************/
/*
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2007 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @ingroup packetapi
* @{
*/
/** @defgroup packet32h Packet.dll definitions and data structures
* Packet32.h contains the data structures and the definitions used by packet.dll.
* The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included
* by the applications that use the functions of this library
* @{
*/
#ifndef __PACKET32
#define __PACKET32
#include <winsock2.h>
#ifdef HAVE_AIRPCAP_API
#include <airpcap.h>
#else
#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
typedef struct _AirpcapHandle* PAirpcapHandle;
#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */
#endif /* HAVE_AIRPCAP_API */
#ifdef HAVE_DAG_API
#include <dagc.h>
#endif /* HAVE_DAG_API */
// Libpcap/wpcap recognizes this macro and knows Npcap Packet API is provided for compilation.
#define HAVE_NPCAP_PACKET_API
// Working modes
#define PACKET_MODE_CAPT 0x0 ///< Capture mode
#define PACKET_MODE_STAT 0x1 ///< Statistical mode
#define PACKET_MODE_MON 0x2 ///< Monitoring mode
#define PACKET_MODE_DUMP 0x10 ///< Dump mode
#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode
/// Alignment macro. Defines the alignment size.
#define Packet_ALIGNMENT sizeof(int)
/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT.
#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))
#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent
#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent
#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent
#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent
#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent
#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent
// Loopback behaviour definitions
#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver
#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver
/*!
\brief Network type structure.
This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed.
*/
typedef struct NetType
{
UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information)
ULONGLONG LinkSpeed; ///< The speed of the network in bits per second
}NetType;
//some definitions stolen from libpcap
#ifndef BPF_MAJOR_VERSION
/*!
\brief A BPF pseudo-assembly program.
The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet.
*/
struct bpf_program
{
UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow.
struct bpf_insn* bf_insns; ///< A pointer to the first instruction of the program.
};
/*!
\brief A single BPF pseudo-instruction.
bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver.
*/
struct bpf_insn
{
USHORT code; ///< Instruction type and addressing mode.
UCHAR jt; ///< Jump if true
UCHAR jf; ///< Jump if false
int k; ///< Generic field used for various purposes.
};
/*!
\brief Structure that contains a couple of statistics values on the current capture.
It is used by packet.dll to return statistics about a capture session.
*/
struct bpf_stat
{
UINT bs_recv; ///< Number of packets that the driver received from the network adapter
///< from the beginning of the current capture. This value includes the packets
///< lost by the driver.
UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture.
///< Basically, a packet is lost when the the buffer of the driver is full.
///< In this situation the packet cannot be stored and the driver rejects it.
UINT ps_ifdrop; ///< drops by interface. XXX not yet supported
UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and
///< thus reach the application.
};
/*!
\brief Packet header.
This structure defines the header associated with every packet delivered to the application.
*/
struct bpf_hdr
{
struct timeval bh_tstamp; ///< The timestamp associated with the captured packet.
///< It is stored in a TimeVal structure.
UINT bh_caplen; ///< Length of captured portion. The captured portion <b>can be different</b>
///< from the original packet, because it is possible (with a proper filter)
///< to instruct the driver to capture only a portion of the packets.
UINT bh_datalen; ///< Original length of packet
USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases,
///< a padding could be added between the end of this structure and the packet
///< data for performance reasons. This filed can be used to retrieve the actual data
///< of the packet.
};
/*!
\brief Dump packet header.
This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets().
It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a
packet in a dump file. This makes straightforward sending WinPcap dump files to the network.
*/
struct dump_bpf_hdr
{
struct timeval ts; ///< Time stamp of the packet
UINT caplen; ///< Length of captured portion. The captured portion can smaller than the
///< the original packet, because it is possible (with a proper filter) to
///< instruct the driver to capture only a portion of the packets.
UINT len; ///< Length of the original packet (off wire).
};
#endif
struct bpf_stat;
#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices
#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links
#define NMAX_PACKET 65535
/*!
\brief Addresses of a network adapter.
This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with
an adapter.
*/
typedef struct npf_if_addr
{
struct sockaddr_storage IPAddress; ///< IP address.
struct sockaddr_storage SubnetMask; ///< Netmask for that address.
struct sockaddr_storage Broadcast; ///< Broadcast address.
}npf_if_addr;
#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API.
#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API.
#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
typedef WAN_ADAPTER* PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter
#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET
#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card
#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file
#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones.
#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card
#define INFO_FLAG_NPFIM_DEVICE 32
/*!
\brief Describes an opened network adapter.
This structure is the most important for the functioning of packet.dll, but the great part of its fields
should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters
*/
typedef struct _ADAPTER
{
HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver.
CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened.
int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated
///< on the wire.
HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter.
///< It can be passed to standard Win32 functions (like WaitForSingleObject
///< or WaitForMultipleObjects) to wait until the driver's buffer contains some
///< data. It is particularly useful in GUI applications that need to wait
///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy()
///< function can be used to define the minimum amount of data in the kernel buffer
///< that will cause the event to be signalled.
UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and
///< ReadEvent will be signaled, also if no packets were captured
CHAR Name[ADAPTER_NAME_LENGTH];
PWAN_ADAPTER pWanAdapter;
UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API.
#ifdef HAVE_AIRPCAP_API
PAirpcapHandle AirpcapAd;
#endif // HAVE_AIRPCAP_API
#ifdef HAVE_NPFIM_API
void* NpfImHandle;
#endif // HAVE_NPFIM_API
#ifdef HAVE_DAG_API
dagc_t* pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter
PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card
struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure
unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry
DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps).
#endif // HAVE_DAG_API
} ADAPTER, * LPADAPTER;
/*!
\brief Structure that contains a group of packets coming from the driver.
This structure defines the header associated with every packet delivered to the application.
*/
typedef struct _PACKET
{
HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications.
OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications.
PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for
///< details about the organization of the data in this buffer
UINT Length; ///< Length of the buffer
DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data
///< received by the last call to PacketReceivePacket()
BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications.
} PACKET, * LPPACKET;
/*!
\brief Structure containing an OID request.
It is used by the PacketRequest() function to send an OID to the interface card driver.
It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address,
the list of the multicast groups defined on it, and so on.
*/
struct _PACKET_OID_DATA
{
ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
///< for a complete list of valid codes.
ULONG Length; ///< Length of the data field
UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received
///< from the adapter.
};
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, * PPACKET_OID_DATA;
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @}
*/
/*
BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName,
CHAR *Value,
UINT *pValueLen,
CHAR *DefaultVal);
BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName,
WCHAR *Value,
UINT *pValueLen,
WCHAR *DefaultVal);
*/
//---------------------------------------------------------------------------
// EXPORTED FUNCTIONS
//---------------------------------------------------------------------------
PCHAR PacketGetVersion();
PCHAR PacketGetDriverVersion();
PCHAR PacketGetDriverName();
BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject, int nbytes);
BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject, int nwrites);
BOOLEAN PacketSetMode(LPADAPTER AdapterObject, int mode);
BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject, int timeout);
BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program* fp);
BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior);
INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen);
BOOLEAN PacketGetStats(LPADAPTER AdapterObject, struct bpf_stat* s);
BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject, struct bpf_stat* s);
BOOLEAN PacketSetBuff(LPADAPTER AdapterObject, int dim);
BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType* type);
BOOLEAN PacketIsLoopbackAdapter(PCHAR AdapterName);
int PacketIsMonitorModeSupported(PCHAR AdapterName);
int PacketSetMonitorMode(PCHAR AdapterName, int mode);
int PacketGetMonitorMode(PCHAR AdapterName);
LPADAPTER PacketOpenAdapter(PCHAR AdapterName);
BOOLEAN PacketSendPacket(LPADAPTER AdapterObject, LPPACKET pPacket, BOOLEAN Sync);
INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync);
LPPACKET PacketAllocatePacket(void);
VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length);
VOID PacketFreePacket(LPPACKET lpPacket);
BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject, LPPACKET lpPacket, BOOLEAN Sync);
BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject, ULONG Filter);
BOOLEAN PacketGetAdapterNames(PCHAR pStr, PULONG BufferSize);
BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries);
BOOLEAN PacketRequest(LPADAPTER AdapterObject, BOOLEAN Set, PPACKET_OID_DATA OidData);
HANDLE PacketGetReadEvent(LPADAPTER AdapterObject);
BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void* name, int len);
BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks);
BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync);
BOOL PacketStopDriver();
BOOL PacketStopDriver60();
VOID PacketCloseAdapter(LPADAPTER lpAdapter);
BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength);
BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags);
PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject);
//
// Used by PacketStartOemEx
//
#define PACKET_START_OEM_NO_NETMON 0x00000001
#ifdef __cplusplus
}
#endif
#endif //__PACKET32

45
include/npcap/pcap-bpf.h Normal file
View File

@ -0,0 +1,45 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* For backwards compatibility.
*
* Note to OS vendors: do NOT get rid of this file! Some applications
* might expect to be able to include <pcap-bpf.h>.
*/
#include <pcap/bpf.h>

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 1994, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* For backwards compatibility.
*
* Note to OS vendors: do NOT get rid of this file! Some applications
* might expect to be able to include <pcap-namedb.h>.
*/
#include <pcap/namedb.h>

126
include/npcap/pcap-stdinc.h Normal file
View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (C) 1999 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef pcap_stdinc_h
#define pcap_stdinc_h
/*
* Avoids a compiler warning in case this was already defined
* (someone defined _WINSOCKAPI_ when including 'windows.h', in order
* to prevent it from including 'winsock.h')
*/
#ifdef _WINSOCKAPI_
#undef _WINSOCKAPI_
#endif
#include <winsock2.h>
#include <fcntl.h>
#include <time.h>
#include <io.h>
#include <ws2tcpip.h>
#if defined(_MSC_VER)
/*
* MSVC.
*/
#if _MSC_VER >= 1800
/*
* VS 2013 or newer; we have <inttypes.h>.
*/
#include <inttypes.h>
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#define u_int64_t uint64_t
#else
/*
* Earlier VS; we have to define this stuff ourselves.
*/
#ifndef HAVE_U_INT8_T
typedef unsigned char u_int8_t;
typedef signed char int8_t;
#endif
#ifndef HAVE_U_INT16_T
typedef unsigned short u_int16_t;
typedef signed short int16_t;
#endif
#ifndef HAVE_U_INT32_T
typedef unsigned int u_int32_t;
typedef signed int int32_t;
#endif
#ifndef HAVE_U_INT64_T
#ifdef _MSC_EXTENSIONS
typedef unsigned _int64 u_int64_t;
typedef _int64 int64_t;
#else /* _MSC_EXTENSIONS */
typedef unsigned long long u_int64_t;
typedef long long int64_t;
#endif
#endif
#endif
#elif defined(__MINGW32__)
#include <stdint.h>
#endif
#endif /* pcap_stdinc_h */

43
include/npcap/pcap.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* For backwards compatibility.
*
* Note to OS vendors: do NOT get rid of this file! Many applications
* expect to be able to include <pcap.h>, and at least some of them
* go through contortions in their configure scripts to try to detect
* OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without
* leaving behind a <pcap.h> file.
*/
#include <pcap/pcap.h>

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2006 Paolo Abeni (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* bluetooth data struct
* By Paolo Abeni <paolo.abeni@email.it>
*/
#ifndef lib_pcap_bluetooth_h
#define lib_pcap_bluetooth_h
/*
* Header prepended libpcap to each bluetooth h4 frame,
* fields are in network byte order
*/
typedef struct _pcap_bluetooth_h4_header {
u_int32_t direction; /* if first bit is set direction is incoming */
} pcap_bluetooth_h4_header;
/*
* Header prepended libpcap to each bluetooth linux monitor frame,
* fields are in network byte order
*/
typedef struct _pcap_bluetooth_linux_monitor_header {
u_int16_t adapter_id;
u_int16_t opcode;
} pcap_bluetooth_linux_monitor_header;
#endif

280
include/npcap/pcap/bpf.h Normal file
View File

@ -0,0 +1,280 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*/
/*
* This is libpcap's cut-down version of bpf.h; it includes only
* the stuff needed for the code generator and the userland BPF
* interpreter, and the libpcap APIs for setting filters, etc..
*
* "pcap-bpf.c" will include the native OS version, as it deals with
* the OS's BPF implementation.
*
* At least two programs found by Google Code Search explicitly includes
* <pcap/bpf.h> (even though <pcap.h>/<pcap/pcap.h> includes it for you),
* so moving that stuff to <pcap/pcap.h> would break the build for some
* programs.
*/
/*
* If we've already included <net/bpf.h>, don't re-define this stuff.
* We assume BSD-style multiple-include protection in <net/bpf.h>,
* which is true of all but the oldest versions of FreeBSD and NetBSD,
* or Tru64 UNIX-style multiple-include protection (or, at least,
* Tru64 UNIX 5.x-style; I don't have earlier versions available to check),
* or AIX-style multiple-include protection (or, at least, AIX 5.x-style;
* I don't have earlier versions available to check), or QNX-style
* multiple-include protection (as per GitHub pull request #394).
*
* We do not check for BPF_MAJOR_VERSION, as that's defined by
* <linux/filter.h>, which is directly or indirectly included in some
* programs that also include pcap.h, and <linux/filter.h> doesn't
* define stuff we need.
*
* This also provides our own multiple-include protection.
*/
#if !defined(_NET_BPF_H_) && !defined(_NET_BPF_H_INCLUDED) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h)
#define lib_pcap_bpf_h
#include <pcap/export-defs.h>
#ifdef __cplusplus
extern "C" {
#endif
/* BSD style release date */
#define BPF_RELEASE 199606
#ifdef MSDOS /* must be 32-bit */
typedef long bpf_int32;
typedef unsigned long bpf_u_int32;
#else
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*
* Tcpdump's print-pflog.c uses this, so we define it here.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
#else
#define BPF_ALIGNMENT sizeof(long)
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
/*
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
#include <pcap/dlt.h>
/*
* The instruction encodings.
*
* Please inform tcpdump-workers@lists.tcpdump.org if you use any
* of the reserved values, so that we can note that they're used
* (and perhaps implement it in the reference BPF implementation
* and encourage its implementation elsewhere).
*/
/*
* The upper 8 bits of the opcode aren't used. BSD/OS used 0x8000.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
/* 0x18 reserved; used by BSD/OS */
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* 0xc0 reserved; used by BSD/OS */
/* 0xe0 reserved; used by BSD/OS */
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_MOD 0x90
#define BPF_XOR 0xa0
/* 0xb0 reserved */
/* 0xc0 reserved */
/* 0xd0 reserved */
/* 0xe0 reserved */
/* 0xf0 reserved */
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
/* 0x50 reserved; used on BSD/OS */
/* 0x60 reserved */
/* 0x70 reserved */
/* 0x80 reserved */
/* 0x90 reserved */
/* 0xa0 reserved */
/* 0xb0 reserved */
/* 0xc0 reserved */
/* 0xd0 reserved */
/* 0xe0 reserved */
/* 0xf0 reserved */
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* 0x18 reserved */
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
/* 0x08 reserved */
/* 0x10 reserved */
/* 0x18 reserved */
/* #define BPF_COP 0x20 NetBSD "coprocessor" extensions */
/* 0x28 reserved */
/* 0x30 reserved */
/* 0x38 reserved */
/* #define BPF_COPX 0x40 NetBSD "coprocessor" extensions */
/* also used on BSD/OS */
/* 0x48 reserved */
/* 0x50 reserved */
/* 0x58 reserved */
/* 0x60 reserved */
/* 0x68 reserved */
/* 0x70 reserved */
/* 0x78 reserved */
#define BPF_TXA 0x80
/* 0x88 reserved */
/* 0x90 reserved */
/* 0x98 reserved */
/* 0xa0 reserved */
/* 0xa8 reserved */
/* 0xb0 reserved */
/* 0xb8 reserved */
/* 0xc0 reserved; used on BSD/OS */
/* 0xc8 reserved */
/* 0xd0 reserved */
/* 0xd8 reserved */
/* 0xe0 reserved */
/* 0xe8 reserved */
/* 0xf0 reserved */
/* 0xf8 reserved */
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_u_int32 k;
};
/*
* Auxiliary data, for use when interpreting a filter intended for the
* Linux kernel when the kernel rejects the filter (requiring us to
* run it in userland). It contains VLAN tag information.
*/
struct bpf_aux_data {
u_short vlan_tag_present;
u_short vlan_tag;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#if __STDC__ || defined(__cplusplus)
PCAP_API int bpf_validate(const struct bpf_insn *, int);
PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *);
#else
PCAP_API int bpf_validate();
PCAP_API u_int bpf_filter();
extern u_int bpf_filter_with_aux_data();
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#ifdef __cplusplus
}
#endif
#endif /* !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) */

View File

@ -0,0 +1,54 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lib_pcap_can_socketcan_h
#define lib_pcap_can_socketcan_h
/*
* SocketCAN header, as per Documentation/networking/can.txt in the
* Linux source.
*/
typedef struct {
u_int32_t can_id;
u_int8_t payload_length;
u_int8_t pad;
u_int8_t reserved1;
u_int8_t reserved2;
} pcap_can_socketcan_hdr;
#endif

1340
include/npcap/pcap/dlt.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lib_pcap_export_defs_h
#define lib_pcap_export_defs_h
/*
* PCAP_API_DEF must be used when defining *data* exported from
* libpcap. It can be used when defining *functions* exported
* from libpcap, but it doesn't have to be used there. It
* should not be used in declarations in headers.
*
* PCAP_API must be used when *declaring* data or functions
* exported from libpcap; PCAP_API_DEF won't work on all platforms.
*/
/*
* Check whether this is GCC major.minor or a later release, or some
* compiler that claims to be "just like GCC" of that version or a
* later release.
*/
#define IS_AT_LEAST_GNUC_VERSION(major, minor) \
(defined(__GNUC__) && \
(__GNUC__ > (major) || \
(__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
#if defined(_WIN32)
#ifdef BUILDING_PCAP
/*
* We're compiling libpcap, so we should export functions in our
* API.
*/
#define PCAP_API_DEF __declspec(dllexport)
#else
#define PCAP_API_DEF __declspec(dllimport)
#endif
#elif defined(MSDOS)
/* XXX - does this need special treatment? */
#define PCAP_API_DEF
#else /* UN*X */
#ifdef BUILDING_PCAP
/*
* We're compiling libpcap, so we should export functions in our API.
* The compiler might be configured not to export functions from a
* shared library by default, so we might have to explicitly mark
* functions as exported.
*/
#if IS_AT_LEAST_GNUC_VERSION(3, 4)
/*
* GCC 3.4 or later, or some compiler asserting compatibility with
* GCC 3.4 or later, so we have __attribute__((visibility()).
*/
#define PCAP_API_DEF __attribute__((visibility("default")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
/*
* Sun C 5.5 or later, so we have __global.
* (Sun C 5.9 and later also have __attribute__((visibility()),
* but there's no reason to prefer it with Sun C.)
*/
#define PCAP_API_DEF __global
#else
/*
* We don't have anything to say.
*/
#define PCAP_API_DEF
#endif
#else
/*
* We're not building libpcap.
*/
#define PCAP_API_DEF
#endif
#endif /* _WIN32/MSDOS/UN*X */
#define PCAP_API PCAP_API_DEF extern
#endif /* lib_pcap_export_defs_h */

View File

@ -0,0 +1,43 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */
#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */
#define IPNET_OUTBOUND 1
#define IPNET_INBOUND 2

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 1994, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lib_pcap_namedb_h
#define lib_pcap_namedb_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* As returned by the pcap_next_etherent()
* XXX this stuff doesn't belong in this interface, but this
* library already must do name to address translation, so
* on systems that don't have support for /etc/ethers, we
* export these hooks since they're already being used by
* some applications (such as tcpdump) and already being
* marked as exported in some OSes offering libpcap (such
* as Debian).
*/
struct pcap_etherent {
u_char addr[6];
char name[122];
};
#ifndef PCAP_ETHERS_FILE
#define PCAP_ETHERS_FILE "/etc/ethers"
#endif
PCAP_API struct pcap_etherent *pcap_next_etherent(FILE *);
PCAP_API u_char *pcap_ether_hostton(const char*);
PCAP_API u_char *pcap_ether_aton(const char *);
PCAP_API bpf_u_int32 **pcap_nametoaddr(const char *);
#ifdef INET6
PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *);
#endif
PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *);
PCAP_API int pcap_nametoport(const char *, int *, int *);
PCAP_API int pcap_nametoportrange(const char *, int *, int *, int *);
PCAP_API int pcap_nametoproto(const char *);
PCAP_API int pcap_nametoeproto(const char *);
PCAP_API int pcap_nametollc(const char *);
/*
* If a protocol is unknown, PROTO_UNDEF is returned.
* Also, pcap_nametoport() returns the protocol along with the port number.
* If there are ambiguous entried in /etc/services (i.e. domain
* can be either tcp or udp) PROTO_UNDEF is returned.
*/
#define PROTO_UNDEF -1
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2013, Petar Alilovic,
* Faculty of Electrical Engineering and Computing, University of Zagreb
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#ifndef lib_pcap_nflog_h
#define lib_pcap_nflog_h
/*
* Structure of an NFLOG header and TLV parts, as described at
* http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
*
* The NFLOG header is big-endian.
*
* The TLV length and type are in host byte order. The value is either
* big-endian or is an array of bytes in some externally-specified byte
* order (text string, link-layer address, link-layer header, packet
* data, etc.).
*/
typedef struct nflog_hdr {
u_int8_t nflog_family; /* address family */
u_int8_t nflog_version; /* version */
u_int16_t nflog_rid; /* resource ID */
} nflog_hdr_t;
typedef struct nflog_tlv {
u_int16_t tlv_length; /* tlv length */
u_int16_t tlv_type; /* tlv type */
/* value follows this */
} nflog_tlv_t;
typedef struct nflog_packet_hdr {
u_int16_t hw_protocol; /* hw protocol */
u_int8_t hook; /* netfilter hook */
u_int8_t pad; /* padding to 32 bits */
} nflog_packet_hdr_t;
typedef struct nflog_hwaddr {
u_int16_t hw_addrlen; /* address length */
u_int16_t pad; /* padding to 32-bit boundary */
u_int8_t hw_addr[8]; /* address, up to 8 bytes */
} nflog_hwaddr_t;
typedef struct nflog_timestamp {
u_int64_t sec;
u_int64_t usec;
} nflog_timestamp_t;
/*
* TLV types.
*/
#define NFULA_PACKET_HDR 1 /* nflog_packet_hdr_t */
#define NFULA_MARK 2 /* packet mark from skbuff */
#define NFULA_TIMESTAMP 3 /* nflog_timestamp_t for skbuff's time stamp */
#define NFULA_IFINDEX_INDEV 4 /* ifindex of device on which packet received (possibly bridge group) */
#define NFULA_IFINDEX_OUTDEV 5 /* ifindex of device on which packet transmitted (possibly bridge group) */
#define NFULA_IFINDEX_PHYSINDEV 6 /* ifindex of physical device on which packet received (not bridge group) */
#define NFULA_IFINDEX_PHYSOUTDEV 7 /* ifindex of physical device on which packet transmitted (not bridge group) */
#define NFULA_HWADDR 8 /* nflog_hwaddr_t for hardware address */
#define NFULA_PAYLOAD 9 /* packet payload */
#define NFULA_PREFIX 10 /* text string - null-terminated, count includes NUL */
#define NFULA_UID 11 /* UID owning socket on which packet was sent/received */
#define NFULA_SEQ 12 /* sequence number of packets on this NFLOG socket */
#define NFULA_SEQ_GLOBAL 13 /* sequence number of pakets on all NFLOG sockets */
#define NFULA_GID 14 /* GID owning socket on which packet was sent/received */
#define NFULA_HWTYPE 15 /* ARPHRD_ type of skbuff's device */
#define NFULA_HWHEADER 16 /* skbuff's MAC-layer header */
#define NFULA_HWLEN 17 /* length of skbuff's MAC-layer header */
#endif

538
include/npcap/pcap/pcap.h Normal file
View File

@ -0,0 +1,538 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lib_pcap_pcap_h
#define lib_pcap_pcap_h
#include <pcap/export-defs.h>
#if defined(_WIN32)
#include <pcap-stdinc.h>
#elif defined(MSDOS)
#include <sys/types.h>
#include <sys/socket.h> /* u_int, u_char etc. */
#else /* UN*X */
#include <sys/types.h>
#include <sys/time.h>
#endif /* _WIN32/MSDOS/UN*X */
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
#include <pcap/bpf.h>
#endif
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Version number of the current version of the pcap file format.
*
* NOTE: this is *NOT* the version number of the libpcap library.
* To fetch the version information for the version of libpcap
* you're using, use pcap_lib_version().
*/
#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
/*
* Compatibility for systems that have a bpf.h that
* predates the bpf typedefs for 64-bit support.
*/
#if BPF_RELEASE - 0 < 199406
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
typedef struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;
typedef struct pcap_if pcap_if_t;
typedef struct pcap_addr pcap_addr_t;
/*
* The first record in the file contains saved values for some
* of the flags used in the printout phases of tcpdump.
* Many fields here are 32 bit ints so compilers won't insert unwanted
* padding; these files need to be interchangeable across architectures.
*
* Do not change the layout of this structure, in any way (this includes
* changes that only affect the length of fields in this structure).
*
* Also, do not change the interpretation of any of the members of this
* structure, in any way (this includes using values other than
* LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
* field).
*
* Instead:
*
* introduce a new structure for the new format, if the layout
* of the structure changed;
*
* send mail to "tcpdump-workers@lists.tcpdump.org", requesting
* a new magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed file
* header;
*
* make the code in "savefile.c" capable of reading files with
* the old file header as well as files with the new file header
* (using the magic number to determine the header format).
*
* Then supply the changes by forking the branch at
*
* https://github.com/the-tcpdump-group/libpcap/issues
*
* and issuing a pull request, so that future versions of libpcap and
* programs that use it (such as tcpdump) will be able to read your new
* capture file format.
*/
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
/*
* Macros for the value returned by pcap_datalink_ext().
*
* If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
* gives the FCS length of packets in the capture.
*/
#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000)
#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28)
#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000)
typedef enum {
PCAP_D_INOUT = 0,
PCAP_D_IN,
PCAP_D_OUT
} pcap_direction_t;
/*
* Generic per-packet information, as supplied by libpcap.
*
* The time stamp can and should be a "struct timeval", regardless of
* whether your system supports 32-bit tv_sec in "struct timeval",
* 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
* and 64-bit applications. The on-disk format of savefiles uses 32-bit
* tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
* and 64-bit versions of libpcap, even if they're on the same platform,
* should supply the appropriate version of "struct timeval", even if
* that's not what the underlying packet capture mechanism supplies.
*/
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
/*
* As returned by the pcap_stats()
*/
struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */
#if defined(_WIN32) && defined(HAVE_REMOTE)
u_int ps_capt; /* number of packets that reach the application */
u_int ps_sent; /* number of packets sent by the server on the network */
u_int ps_netdrop; /* number of packets lost on the network */
#endif /* _WIN32 && HAVE_REMOTE */
};
#ifdef MSDOS
/*
* As returned by the pcap_stats_ex()
*/
struct pcap_stat_ex {
u_long rx_packets; /* total packets received */
u_long tx_packets; /* total packets transmitted */
u_long rx_bytes; /* total bytes received */
u_long tx_bytes; /* total bytes transmitted */
u_long rx_errors; /* bad packets received */
u_long tx_errors; /* packet transmit problems */
u_long rx_dropped; /* no space in Rx buffers */
u_long tx_dropped; /* no space available for Tx */
u_long multicast; /* multicast packets received */
u_long collisions;
/* detailed rx_errors: */
u_long rx_length_errors;
u_long rx_over_errors; /* receiver ring buff overflow */
u_long rx_crc_errors; /* recv'd pkt with crc error */
u_long rx_frame_errors; /* recv'd frame alignment error */
u_long rx_fifo_errors; /* recv'r fifo overrun */
u_long rx_missed_errors; /* recv'r missed packet */
/* detailed tx_errors */
u_long tx_aborted_errors;
u_long tx_carrier_errors;
u_long tx_fifo_errors;
u_long tx_heartbeat_errors;
u_long tx_window_errors;
};
#endif
/*
* Item in a list of interfaces.
*/
struct pcap_if {
struct pcap_if *next;
char *name; /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
#define PCAP_IF_UP 0x00000002 /* interface is up */
#define PCAP_IF_RUNNING 0x00000004 /* interface is running */
/*
* Representation of an interface address.
*/
struct pcap_addr {
struct pcap_addr *next;
struct sockaddr *addr; /* address */
struct sockaddr *netmask; /* netmask for that address */
struct sockaddr *broadaddr; /* broadcast address for that address */
struct sockaddr *dstaddr; /* P2P destination address for that address */
};
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
/*
* Error codes for the pcap API.
* These will all be negative, so you can check for the success or
* failure of a call that returns these codes by checking for a
* negative value.
*/
#define PCAP_ERROR -1 /* generic error code */
#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12 /* the requested time stamp precision is not supported */
/*
* Warning codes for the pcap API.
* These will all be positive and non-zero, so they won't look like
* errors.
*/
#define PCAP_WARNING 1 /* generic warning code */
#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */
/*
* Value to pass to pcap_compile() as the netmask if you don't know what
* the netmask is.
*/
#define PCAP_NETMASK_UNKNOWN 0xffffffff
PCAP_API char *pcap_lookupdev(char *);
PCAP_API int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
PCAP_API pcap_t *pcap_create(const char *, char *);
PCAP_API int pcap_set_snaplen(pcap_t *, int);
PCAP_API int pcap_set_promisc(pcap_t *, int);
PCAP_API int pcap_can_set_rfmon(pcap_t *);
PCAP_API int pcap_set_rfmon(pcap_t *, int);
PCAP_API int pcap_set_timeout(pcap_t *, int);
PCAP_API int pcap_set_tstamp_type(pcap_t *, int);
PCAP_API int pcap_set_immediate_mode(pcap_t *, int);
PCAP_API int pcap_set_buffer_size(pcap_t *, int);
PCAP_API int pcap_set_tstamp_precision(pcap_t *, int);
PCAP_API int pcap_get_tstamp_precision(pcap_t *);
PCAP_API int pcap_activate(pcap_t *);
PCAP_API int pcap_list_tstamp_types(pcap_t *, int **);
PCAP_API void pcap_free_tstamp_types(int *);
PCAP_API int pcap_tstamp_type_name_to_val(const char *);
PCAP_API const char *pcap_tstamp_type_val_to_name(int);
PCAP_API const char *pcap_tstamp_type_val_to_description(int);
/*
* Time stamp types.
* Not all systems and interfaces will necessarily support all of these.
*
* A system that supports PCAP_TSTAMP_HOST is offering time stamps
* provided by the host machine, rather than by the capture device,
* but not committing to any characteristics of the time stamp;
* it will not offer any of the PCAP_TSTAMP_HOST_ subtypes.
*
* PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine,
* that's low-precision but relatively cheap to fetch; it's normally done
* using the system clock, so it's normally synchronized with times you'd
* fetch from system calls.
*
* PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine,
* that's high-precision; it might be more expensive to fetch. It might
* or might not be synchronized with the system clock, and might have
* problems with time stamps for packets received on different CPUs,
* depending on the platform.
*
* PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the
* capture device; it's synchronized with the system clock.
*
* PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by
* the capture device; it's not synchronized with the system clock.
*
* Note that time stamps synchronized with the system clock can go
* backwards, as the system clock can go backwards. If a clock is
* not in sync with the system clock, that could be because the
* system clock isn't keeping accurate time, because the other
* clock isn't keeping accurate time, or both.
*
* Note that host-provided time stamps generally correspond to the
* time when the time-stamping code sees the packet; this could
* be some unknown amount of time after the first or last bit of
* the packet is received by the network adapter, due to batching
* of interrupts for packet arrival, queueing delays, etc..
*/
#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */
#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */
#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */
#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */
#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */
/*
* Time stamp resolution types.
* Not all systems and interfaces will necessarily support all of these
* resolutions when doing live captures; all of them can be requested
* when reading a savefile.
*/
#define PCAP_TSTAMP_PRECISION_MICRO 0 /* use timestamps with microsecond precision, default */
#define PCAP_TSTAMP_PRECISION_NANO 1 /* use timestamps with nanosecond precision */
PCAP_API pcap_t *pcap_open_live(const char *, int, int, int, char *);
PCAP_API pcap_t *pcap_open_dead(int, int);
PCAP_API pcap_t *pcap_open_dead_with_tstamp_precision(int, int, u_int);
PCAP_API pcap_t *pcap_open_offline_with_tstamp_precision(const char *, u_int, char *);
PCAP_API pcap_t *pcap_open_offline(const char *, char *);
#ifdef _WIN32
PCAP_API pcap_t *pcap_hopen_offline_with_tstamp_precision(intptr_t, u_int, char *);
PCAP_API pcap_t *pcap_hopen_offline(intptr_t, char *);
/*
* If we're building libpcap, these are internal routines in savefile.c,
* so we mustn't define them as macros.
*/
#ifndef BUILDING_PCAP
#define pcap_fopen_offline_with_tstamp_precision(f,p,b) \
pcap_hopen_offline_with_tstamp_precision(_get_osfhandle(_fileno(f)), p, b)
#define pcap_fopen_offline(f,b) \
pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
#endif
#else /*_WIN32*/
PCAP_API pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *);
PCAP_API pcap_t *pcap_fopen_offline(FILE *, char *);
#endif /*_WIN32*/
PCAP_API void pcap_close(pcap_t *);
PCAP_API int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
PCAP_API int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
PCAP_API const u_char *pcap_next(pcap_t *, struct pcap_pkthdr *);
PCAP_API int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
PCAP_API void pcap_breakloop(pcap_t *);
PCAP_API int pcap_stats(pcap_t *, struct pcap_stat *);
PCAP_API int pcap_setfilter(pcap_t *, struct bpf_program *);
PCAP_API int pcap_setdirection(pcap_t *, pcap_direction_t);
PCAP_API int pcap_getnonblock(pcap_t *, char *);
PCAP_API int pcap_setnonblock(pcap_t *, int, char *);
PCAP_API int pcap_inject(pcap_t *, const void *, size_t);
PCAP_API int pcap_sendpacket(pcap_t *, const u_char *, int);
PCAP_API const char *pcap_statustostr(int);
PCAP_API const char *pcap_strerror(int);
PCAP_API char *pcap_geterr(pcap_t *);
PCAP_API void pcap_perror(pcap_t *, const char *);
PCAP_API int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
bpf_u_int32);
PCAP_API int pcap_compile_nopcap(int, int, struct bpf_program *,
const char *, int, bpf_u_int32);
PCAP_API void pcap_freecode(struct bpf_program *);
PCAP_API int pcap_offline_filter(const struct bpf_program *,
const struct pcap_pkthdr *, const u_char *);
PCAP_API int pcap_datalink(pcap_t *);
PCAP_API int pcap_datalink_ext(pcap_t *);
PCAP_API int pcap_list_datalinks(pcap_t *, int **);
PCAP_API int pcap_set_datalink(pcap_t *, int);
PCAP_API void pcap_free_datalinks(int *);
PCAP_API int pcap_datalink_name_to_val(const char *);
PCAP_API const char *pcap_datalink_val_to_name(int);
PCAP_API const char *pcap_datalink_val_to_description(int);
PCAP_API int pcap_snapshot(pcap_t *);
PCAP_API int pcap_is_swapped(pcap_t *);
PCAP_API int pcap_major_version(pcap_t *);
PCAP_API int pcap_minor_version(pcap_t *);
/* XXX */
PCAP_API FILE *pcap_file(pcap_t *);
PCAP_API int pcap_fileno(pcap_t *);
#ifdef _WIN32
PCAP_API int pcap_wsockinit(void);
#endif
PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *);
PCAP_API FILE *pcap_dump_file(pcap_dumper_t *);
PCAP_API long pcap_dump_ftell(pcap_dumper_t *);
PCAP_API int pcap_dump_flush(pcap_dumper_t *);
PCAP_API void pcap_dump_close(pcap_dumper_t *);
PCAP_API void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
PCAP_API int pcap_findalldevs(pcap_if_t **, char *);
PCAP_API void pcap_freealldevs(pcap_if_t *);
PCAP_API const char *pcap_lib_version(void);
/*
* On at least some versions of NetBSD and QNX, we don't want to declare
* bpf_filter() here, as it's also be declared in <net/bpf.h>, with a
* different signature, but, on other BSD-flavored UN*Xes, it's not
* declared in <net/bpf.h>, so we *do* want to declare it here, so it's
* declared when we build pcap-bpf.c.
*/
#if !defined(__NetBSD__) && !defined(__QNX__)
PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
#endif
PCAP_API int bpf_validate(const struct bpf_insn *f, int len);
PCAP_API char *bpf_image(const struct bpf_insn *, int);
PCAP_API void bpf_dump(const struct bpf_program *, int);
#if defined(_WIN32)
/*
* Win32 definitions
*/
/*!
\brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit().
*/
struct pcap_send_queue
{
u_int maxlen; /* Maximum size of the the queue, in bytes. This
variable contains the size of the buffer field. */
u_int len; /* Current size of the queue, in bytes. */
char *buffer; /* Buffer containing the packets to be sent. */
};
typedef struct pcap_send_queue pcap_send_queue;
/*!
\brief This typedef is a support for the pcap_get_airpcap_handle() function
*/
#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
typedef struct _AirpcapHandle *PAirpcapHandle;
#endif
PCAP_API int pcap_setbuff(pcap_t *p, int dim);
PCAP_API int pcap_setmode(pcap_t *p, int mode);
PCAP_API int pcap_setmintocopy(pcap_t *p, int size);
PCAP_API HANDLE pcap_getevent(pcap_t *p);
PCAP_API int pcap_oid_get_request(pcap_t *, bpf_u_int32, void *, size_t *);
PCAP_API int pcap_oid_set_request(pcap_t *, bpf_u_int32, const void *, size_t *);
PCAP_API pcap_send_queue* pcap_sendqueue_alloc(u_int memsize);
PCAP_API void pcap_sendqueue_destroy(pcap_send_queue* queue);
PCAP_API int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data);
PCAP_API u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync);
PCAP_API struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size);
PCAP_API int pcap_setuserbuffer(pcap_t *p, int size);
PCAP_API int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks);
PCAP_API int pcap_live_dump_ended(pcap_t *p, int sync);
PCAP_API int pcap_start_oem(char* err_str, int flags);
PCAP_API PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p);
#define MODE_CAPT 0
#define MODE_STAT 1
#define MODE_MON 2
#elif defined(MSDOS)
/*
* MS-DOS definitions
*/
PCAP_API int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
PCAP_API void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
PCAP_API u_long pcap_mac_packets (void);
#else /* UN*X */
/*
* UN*X definitions
*/
PCAP_API int pcap_get_selectable_fd(pcap_t *);
#endif /* _WIN32/MSDOS/UN*X */
#ifdef HAVE_REMOTE
/* Includes most of the public stuff that is needed for the remote capture */
#include <remote-ext.h>
#endif /* HAVE_REMOTE */
#ifdef __cplusplus
}
#endif
#endif /* lib_pcap_pcap_h */

129
include/npcap/pcap/sll.h Normal file
View File

@ -0,0 +1,129 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* For captures on Linux cooked sockets, we construct a fake header
* that includes:
*
* a 2-byte "packet type" which is one of:
*
* LINUX_SLL_HOST packet was sent to us
* LINUX_SLL_BROADCAST packet was broadcast
* LINUX_SLL_MULTICAST packet was multicast
* LINUX_SLL_OTHERHOST packet was sent to somebody else
* LINUX_SLL_OUTGOING packet was sent *by* us;
*
* a 2-byte Ethernet protocol field;
*
* a 2-byte link-layer type;
*
* a 2-byte link-layer address length;
*
* an 8-byte source link-layer address, whose actual length is
* specified by the previous value.
*
* All fields except for the link-layer address are in network byte order.
*
* DO NOT change the layout of this structure, or change any of the
* LINUX_SLL_ values below. If you must change the link-layer header
* for a "cooked" Linux capture, introduce a new DLT_ type (ask
* "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
* a value that collides with a value already being used), and use the
* new header in captures of that type, so that programs that can
* handle DLT_LINUX_SLL captures will continue to handle them correctly
* without any change, and so that capture files with different headers
* can be told apart and programs that read them can dissect the
* packets in them.
*/
#ifndef lib_pcap_sll_h
#define lib_pcap_sll_h
/*
* A DLT_LINUX_SLL fake link-layer header.
*/
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */
struct sll_header {
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype; /* link-layer address type */
u_int16_t sll_halen; /* link-layer address length */
u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
u_int16_t sll_protocol; /* protocol */
};
/*
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
* PACKET_ values on Linux, but are defined here so that they're
* available even on systems other than Linux, and so that they
* don't change even if the PACKET_ values change.
*/
#define LINUX_SLL_HOST 0
#define LINUX_SLL_BROADCAST 1
#define LINUX_SLL_MULTICAST 2
#define LINUX_SLL_OTHERHOST 3
#define LINUX_SLL_OUTGOING 4
/*
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
* ETH_P_ values on Linux, but are defined here so that they're
* available even on systems other than Linux. We assume, for now,
* that the ETH_P_ values won't change in Linux; if they do, then:
*
* if we don't translate them in "pcap-linux.c", capture files
* won't necessarily be readable if captured on a system that
* defines ETH_P_ values that don't match these values;
*
* if we do translate them in "pcap-linux.c", that makes life
* unpleasant for the BPF code generator, as the values you test
* for in the kernel aren't the values that you test for when
* reading a capture file, so the fixup code run on BPF programs
* handed to the kernel ends up having to do more work.
*
* Add other values here as necessary, for handling packet types that
* might show up on non-Ethernet, non-802.x networks. (Not all the ones
* in the Linux "if_ether.h" will, I suspect, actually show up in
* captures.)
*/
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
#define LINUX_SLL_P_CAN 0x000C /* CAN frames, with SocketCAN pseudo-headers */
#define LINUX_SLL_P_CANFD 0x000D /* CAN FD frames, with SocketCAN pseudo-headers */
#endif

141
include/npcap/pcap/usb.h Normal file
View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2006 Paolo Abeni (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Basic USB data struct
* By Paolo Abeni <paolo.abeni@email.it>
*/
#ifndef lib_pcap_usb_h
#define lib_pcap_usb_h
/*
* possible transfer mode
*/
#define URB_TRANSFER_IN 0x80
#define URB_ISOCHRONOUS 0x0
#define URB_INTERRUPT 0x1
#define URB_CONTROL 0x2
#define URB_BULK 0x3
/*
* possible event type
*/
#define URB_SUBMIT 'S'
#define URB_COMPLETE 'C'
#define URB_ERROR 'E'
/*
* USB setup header as defined in USB specification.
* Appears at the front of each Control S-type packet in DLT_USB captures.
*/
typedef struct _usb_setup {
u_int8_t bmRequestType;
u_int8_t bRequest;
u_int16_t wValue;
u_int16_t wIndex;
u_int16_t wLength;
} pcap_usb_setup;
/*
* Information from the URB for Isochronous transfers.
*/
typedef struct _iso_rec {
int32_t error_count;
int32_t numdesc;
} iso_rec;
/*
* Header prepended by linux kernel to each event.
* Appears at the front of each packet in DLT_USB_LINUX captures.
*/
typedef struct _usb_header {
u_int64_t id;
u_int8_t event_type;
u_int8_t transfer_type;
u_int8_t endpoint_number;
u_int8_t device_address;
u_int16_t bus_id;
char setup_flag;/*if !=0 the urb setup header is not present*/
char data_flag; /*if !=0 no urb data is present*/
int64_t ts_sec;
int32_t ts_usec;
int32_t status;
u_int32_t urb_len;
u_int32_t data_len; /* amount of urb data really present in this event*/
pcap_usb_setup setup;
} pcap_usb_header;
/*
* Header prepended by linux kernel to each event for the 2.6.31
* and later kernels; for the 2.6.21 through 2.6.30 kernels, the
* "iso_rec" information, and the fields starting with "interval"
* are zeroed-out padding fields.
*
* Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures.
*/
typedef struct _usb_header_mmapped {
u_int64_t id;
u_int8_t event_type;
u_int8_t transfer_type;
u_int8_t endpoint_number;
u_int8_t device_address;
u_int16_t bus_id;
char setup_flag;/*if !=0 the urb setup header is not present*/
char data_flag; /*if !=0 no urb data is present*/
int64_t ts_sec;
int32_t ts_usec;
int32_t status;
u_int32_t urb_len;
u_int32_t data_len; /* amount of urb data really present in this event*/
union {
pcap_usb_setup setup;
iso_rec iso;
} s;
int32_t interval; /* for Interrupt and Isochronous events */
int32_t start_frame; /* for Isochronous events */
u_int32_t xfer_flags; /* copy of URB's transfer flags */
u_int32_t ndesc; /* number of isochronous descriptors */
} pcap_usb_header_mmapped;
/*
* Isochronous descriptors; for isochronous transfers there might be
* one or more of these at the beginning of the packet data. The
* number of descriptors is given by the "ndesc" field in the header;
* as indicated, in older kernels that don't put the descriptors at
* the beginning of the packet, that field is zeroed out, so that field
* can be trusted even in captures from older kernels.
*/
typedef struct _usb_isodesc {
int32_t status;
u_int32_t offset;
u_int32_t len;
u_int8_t pad[4];
} usb_isodesc;
#endif

44
include/npcap/pcap/vlan.h Normal file
View File

@ -0,0 +1,44 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lib_pcap_vlan_h
#define lib_pcap_vlan_h
struct vlan_tag {
u_int16_t vlan_tpid; /* ETH_P_8021Q */
u_int16_t vlan_tci; /* VLAN TCI */
};
#define VLAN_TAG_LEN 4
#endif

467
include/npcap/remote-ext.h Normal file
View File

@ -0,0 +1,467 @@
/*
* Copyright (c) 2002 - 2003
* NetGroup, Politecnico di Torino (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __REMOTE_EXT_H__
#define __REMOTE_EXT_H__
#ifndef HAVE_REMOTE
#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h
#endif
/*// Definition for Microsoft Visual Studio */
#if _MSC_VER > 1000
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* \file remote-ext.h
*
* The goal of this file it to include most of the new definitions that should be
* placed into the pcap.h file.
*
* It includes all new definitions (structures and functions like pcap_open().
* Some of the functions are not really a remote feature, but, right now,
* they are placed here.
*/
/*// All this stuff is public */
/*
* \addtogroup remote_struct
* \{
*/
/*
* \brief Defines the maximum buffer size in which address, port, interface names are kept.
*
* In case the adapter name or such is larger than this value, it is truncated.
* This is not used by the user; however it must be aware that an hostname / interface
* name longer than this value will be truncated.
*/
#define PCAP_BUF_SIZE 1024
/*
* \addtogroup remote_source_ID
* \{
*/
/*
* \brief Internal representation of the type of source in use (file,
* remote/local interface).
*
* This indicates a file, i.e. the user want to open a capture from a local file.
*/
#define PCAP_SRC_FILE 2
/*
* \brief Internal representation of the type of source in use (file,
* remote/local interface).
*
* This indicates a local interface, i.e. the user want to open a capture from
* a local interface. This does not involve the RPCAP protocol.
*/
#define PCAP_SRC_IFLOCAL 3
/*
* \brief Internal representation of the type of source in use (file,
* remote/local interface).
*
* This indicates a remote interface, i.e. the user want to open a capture from
* an interface on a remote host. This does involve the RPCAP protocol.
*/
#define PCAP_SRC_IFREMOTE 4
/*
* \}
*/
/* \addtogroup remote_source_string
*
* The formats allowed by the pcap_open() are the following:
* - file://path_and_filename [opens a local file]
* - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol]
* - rpcap://host/devicename [opens the selected device available on a remote host]
* - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP]
* - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged]
* - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged]
*
* The formats allowed by the pcap_findalldevs_ex() are the following:
* - file://folder/ [lists all the files in the given folder]
* - rpcap:// [lists all local adapters]
* - rpcap://host:port/ [lists the devices available on a remote host]
*
* Referring to the 'host' and 'port' parameters, they can be either numeric or literal. Since
* IPv6 is fully supported, these are the allowed formats:
*
* - host (literal): e.g. host.foo.bar
* - host (numeric IPv4): e.g. 10.11.12.13
* - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13]
* - host (numeric IPv6): e.g. [1:2:3::4]
* - port: can be either numeric (e.g. '80') or literal (e.g. 'http')
*
* Here you find some allowed examples:
* - rpcap://host.foo.bar/devicename [everything literal, no port number]
* - rpcap://host.foo.bar:1234/devicename [everything literal, with port number]
* - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number]
* - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number]
* - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number]
* - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number]
* - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number]
* - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number]
*
* \{
*/
/*
* \brief String that will be used to determine the type of source in use (file,
* remote/local interface).
*
* This string will be prepended to the interface name in order to create a string
* that contains all the information required to open the source.
*
* This string indicates that the user wants to open a capture from a local file.
*/
#define PCAP_SRC_FILE_STRING "file://"
/*
* \brief String that will be used to determine the type of source in use (file,
* remote/local interface).
*
* This string will be prepended to the interface name in order to create a string
* that contains all the information required to open the source.
*
* This string indicates that the user wants to open a capture from a network interface.
* This string does not necessarily involve the use of the RPCAP protocol. If the
* interface required resides on the local host, the RPCAP protocol is not involved
* and the local functions are used.
*/
#define PCAP_SRC_IF_STRING "rpcap://"
/*
* \}
*/
/*
* \addtogroup remote_open_flags
* \{
*/
/*
* \brief Defines if the adapter has to go in promiscuous mode.
*
* It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise.
* Note that even if this parameter is false, the interface could well be in promiscuous
* mode for some other reason (for example because another capture process with
* promiscuous mode enabled is currently using that interface).
* On on Linux systems with 2.2 or later kernels (that have the "any" device), this
* flag does not work on the "any" device; if an argument of "any" is supplied,
* the 'promisc' flag is ignored.
*/
#define PCAP_OPENFLAG_PROMISCUOUS 1
/*
* \brief Defines if the data transfer (in case of a remote
* capture) has to be done with UDP protocol.
*
* If it is '1' if you want a UDP data connection, '0' if you want
* a TCP data connection; control connection is always TCP-based.
* A UDP connection is much lighter, but it does not guarantee that all
* the captured packets arrive to the client workstation. Moreover,
* it could be harmful in case of network congestion.
* This flag is meaningless if the source is not a remote interface.
* In that case, it is simply ignored.
*/
#define PCAP_OPENFLAG_DATATX_UDP 2
/*
* \brief Defines if the remote probe will capture its own generated traffic.
*
* In case the remote probe uses the same interface to capture traffic and to send
* data back to the caller, the captured traffic includes the RPCAP traffic as well.
* If this flag is turned on, the RPCAP traffic is excluded from the capture, so that
* the trace returned back to the collector is does not include this traffic.
*/
#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4
/*
* \brief Defines if the local adapter will capture its own generated traffic.
*
* This flag tells the underlying capture driver to drop the packets that were sent by itself.
* This is useful when building applications like bridges, that should ignore the traffic
* they just sent.
*/
#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8
/*
* \brief This flag configures the adapter for maximum responsiveness.
*
* In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before
* copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage,
* i.e. better performance, which is good for applications like sniffers. If the user sets the
* PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application
* is ready to receive them. This is suggested for real time applications (like, for example, a bridge)
* that need the best responsiveness.
*/
#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16
/*
* \}
*/
/*
* \addtogroup remote_samp_methods
* \{
*/
/*
*\brief No sampling has to be done on the current capture.
*
* In this case, no sampling algorithms are applied to the current capture.
*/
#define PCAP_SAMP_NOSAMP 0
/*
* \brief It defines that only 1 out of N packets must be returned to the user.
*
* In this case, the 'value' field of the 'pcap_samp' structure indicates the
* number of packets (minus 1) that must be discarded before one packet got accepted.
* In other words, if 'value = 10', the first packet is returned to the caller, while
* the following 9 are discarded.
*/
#define PCAP_SAMP_1_EVERY_N 1
/*
* \brief It defines that we have to return 1 packet every N milliseconds.
*
* In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting
* time' in milliseconds before one packet got accepted.
* In other words, if 'value = 10', the first packet is returned to the caller; the next
* returned one will be the first packet that arrives when 10ms have elapsed.
*/
#define PCAP_SAMP_FIRST_AFTER_N_MS 2
/*
* \}
*/
/*
* \addtogroup remote_auth_methods
* \{
*/
/*
* \brief It defines the NULL authentication.
*
* This value has to be used within the 'type' member of the pcap_rmtauth structure.
* The 'NULL' authentication has to be equal to 'zero', so that old applications
* can just put every field of struct pcap_rmtauth to zero, and it does work.
*/
#define RPCAP_RMTAUTH_NULL 0
/*
* \brief It defines the username/password authentication.
*
* With this type of authentication, the RPCAP protocol will use the username/
* password provided to authenticate the user on the remote machine. If the
* authentication is successful (and the user has the right to open network devices)
* the RPCAP connection will continue; otherwise it will be dropped.
*
* This value has to be used within the 'type' member of the pcap_rmtauth structure.
*/
#define RPCAP_RMTAUTH_PWD 1
/*
* \}
*/
/*
* \brief This structure keeps the information needed to autheticate
* the user on a remote machine.
*
* The remote machine can either grant or refuse the access according
* to the information provided.
* In case the NULL authentication is required, both 'username' and
* 'password' can be NULL pointers.
*
* This structure is meaningless if the source is not a remote interface;
* in that case, the functions which requires such a structure can accept
* a NULL pointer as well.
*/
struct pcap_rmtauth
{
/*
* \brief Type of the authentication required.
*
* In order to provide maximum flexibility, we can support different types
* of authentication based on the value of this 'type' variable. The currently
* supported authentication methods are defined into the
* \link remote_auth_methods Remote Authentication Methods Section\endlink.
*/
int type;
/*
* \brief Zero-terminated string containing the username that has to be
* used on the remote machine for authentication.
*
* This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
* and it can be NULL.
*/
char *username;
/*
* \brief Zero-terminated string containing the password that has to be
* used on the remote machine for authentication.
*
* This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
* and it can be NULL.
*/
char *password;
};
/*
* \brief This structure defines the information related to sampling.
*
* In case the sampling is requested, the capturing device should read
* only a subset of the packets coming from the source. The returned packets depend
* on the sampling parameters.
*
* \warning The sampling process is applied <strong>after</strong> the filtering process.
* In other words, packets are filtered first, then the sampling process selects a
* subset of the 'filtered' packets and it returns them to the caller.
*/
struct pcap_samp
{
/*
* Method used for sampling. Currently, the supported methods are listed in the
* \link remote_samp_methods Sampling Methods Section\endlink.
*/
int method;
/*
* This value depends on the sampling method defined. For its meaning, please check
* at the \link remote_samp_methods Sampling Methods Section\endlink.
*/
int value;
};
// Maximum length of an host name (needed for the RPCAP active mode)
#define RPCAP_HOSTLIST_SIZE 1024
/*
* \}
*/ // end of public documentation
// Exported functions
/*
* \name New WinPcap functions
*
* This section lists the new functions that are able to help considerably in writing
* WinPcap programs because of their easiness of use.
*/
// \{
PCAP_API pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
PCAP_API int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf);
PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf);
PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
// \}
// End of new WinPcap functions
/*
* \name Remote Capture functions
*/
/*
* Some minor differences between UN*X sockets and and Winsock sockets.
*/
#ifndef _WIN32
/*!
* \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
* a file descriptor, and therefore a signed integer.
* We define SOCKET to be a signed integer on UN*X, so that it can
* be used on both platforms.
*/
#define SOCKET int
/*!
* \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
* in UN*X, it's -1.
* We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
* both platforms.
*/
#define INVALID_SOCKET -1
#endif
// \{
PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf);
PCAP_API int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf);
PCAP_API int pcap_remoteact_close(const char *host, char *errbuf);
PCAP_API void pcap_remoteact_cleanup();
// \}
// End of remote capture functions
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,9 +1,3 @@
cmake_minimum_required(VERSION 3.1)
project(gsplus VERSION 0.14)
#
# cmake -DCMAKE_BUILD_TYPE=Release
#
INCLUDE (CheckFunctionExists)
INCLUDE (CheckLibraryExists)
@ -20,22 +14,36 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED TRUE)
set(__MSVC__ ${MSVC})
set(__CLANG__ FALSE)
set(__GCC__ FALSE)
if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
set(__CLANG__ TRUE)
endif()
if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
set(__GCC__ TRUE)
endif()
if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()
if(__CLANG__)
add_compile_options(
-O2 -Wall -fomit-frame-pointer
-Wall -fomit-frame-pointer
)
endif()
if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
if(__GCC__)
add_compile_options(
-O2 -Wall -fomit-frame-pointer
-Wall -fomit-frame-pointer
)
endif()
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(NOT IS_BIG_ENDIAN)
add_definitions(-DGSPLUS_LITTLE_ENDIAN)
@ -45,14 +53,30 @@ endif()
pkg_check_modules(SDL2 sdl2)
pkg_check_modules(FREETYPE2 freetype2)
find_program(PERL perl)
find_program(RE2C re2c)
if (RE2C-NOTFOUND)
message(FATAL_ERROR "unable to find re2c")
endif()
if (PERL-NOTFOUND)
message(FATAL_ERROR "unable to find perl")
endif()
#
# run ccmake, cmake -LH, or cmake -D...
#
set(DRIVER "SDL" CACHE STRING "Driver (SDL, X11, WIN32, FB, or HEADLESS")
option(DEBUGGER "Enable the debugger" ON)
option(HOST_FST "Enable host fst support" ON)
option(WITH_DEBUGGER "Enable the debugger" OFF)
option(WITH_HOST_FST "Enable host fst support" ON)
option(TOGGLE_STATUS "Enable F10 Toggle Status support (win32/x11)" OFF)
option(WITH_RAWNET "Enable Uthernet emulation" OFF)
option(WITH_ATBRIDGE "Enable AT Bridge" OFF)
option(WITH_STATIC "Enable static link" OFF)
set(READLINE "AUTO" CACHE STRING "Readline library (AUTO, NONE, READLINE, LIBEDIT)")
set(generated_headers 8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h size_c.h size_s.h 8size_s.h 16size_s.h)
add_custom_command(
@ -76,17 +100,30 @@ add_custom_command(
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if(CYGWIN OR MSYS)
set(WIN32 1)
add_definitions(-DWIN32 -D_WIN32)
endif()
add_custom_command(
OUTPUT debug_shell.c
COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_shell.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_shell.re2c"
MAIN_DEPENDENCY debug_shell.re2c
)
if(WIN32)
add_definitions(-D__USE_W32_SOCKETS -D_WINSOCK2API_)
endif()
add_custom_command(
OUTPUT debug_template.c
COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_template.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_template.re2c"
MAIN_DEPENDENCY debug_template.re2c
)
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_custom_command(
OUTPUT debug_sweet16.c
COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_sweet16.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_sweet16.re2c"
MAIN_DEPENDENCY debug_sweet16.re2c
)
if (WITH_STATIC)
if(__CLANG__ OR __GCC__)
#add_link_options(-static) # 3.13
link_libraries(-static)
endif()
endif()
@ -94,7 +131,8 @@ add_executable(to_pro to_pro.c)
add_executable(partls partls.c)
add_subdirectory(atbridge)
add_subdirectory(tfe)
#add_subdirectory(tfe)
add_subdirectory(rawnet)
if (DRIVER MATCHES "SDL")
set(driver_code sdl2_driver.c sdl2snd_driver.c)
@ -103,7 +141,7 @@ elseif(DRIVER MATCHES "X11")
elseif(DRIVER MATCHES "FB")
set(driver_code fbdriver.c)
elseif(DRIVER MATCHES "WIN32")
set(driver_code scc_windriver.c win32snd_driver.c win_console.c win_generic.c)
set(driver_code win32snd_driver.c win_console.c win_generic.c)
elseif(DRIVER MATCHES "HEADLESS")
set(driver_code headless_driver.c)
else()
@ -128,32 +166,83 @@ set(MACOSX_BUNDLE_GUI_IDENTIFIER com.dagenbrock.gsplus)
# https://cmake.org/Wiki/CMake:Bundles_And_Frameworks
# OS X properties.
add_executable(GSplus WIN32 MACOSX_BUNDLE
adb.c clock.c config.c dis.c engine_c.c scc.c iwm.c
adb.c clock.c config.c engine_c.c scc.c iwm.c
joystick_driver.c moremem.c paddles.c parallel.c printer.cpp sim65816.c
smartport.c sound.c sound_driver.c video.c scc_socket_driver.c glog.c
imagewriter.cpp scc_imagewriter.c scc_llap.c options.c
$<$<BOOL:${DEBUGGER}>:debug.c>
$<$<BOOL:${HOST_FST}>:${host_fst_code}>
disasm.c
debug_shell.c
debug_template.c
debug_sweet16.c
$<$<BOOL:${WITH_DEBUGGER}>:debug.c>
$<$<BOOL:${WITH_HOST_FST}>:${host_fst_code}>
${driver_code}
${generated_headers}
$<$<BOOL:${WIN32}>:scc_windriver.c>
$<$<BOOL:${WIN32}>:win32.rc>
$<$<BOOL:${APPLE}>:gsp_icon.icns>
$<$<BOOL:${APPLE}>:assets/gsp_icon.icns>
$<$<BOOL:${APPLE}>:assets/GSBug.Templates>
$<$<BOOL:${APPLE}>:assets/NList.Data>
$<$<BOOL:${APPLE}>:fix_mac_menu.m>
)
SET_SOURCE_FILES_PROPERTIES(
gsp_icon.icns
assets/gsp_icon.icns
PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)
)
target_link_libraries(GSplus atbridge)
target_link_libraries(GSplus tfe)
SET_SOURCE_FILES_PROPERTIES(
assets/GSBug.Templates
assets/NList.Data
PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)
if (DRIVER MATCHES "WIN32")
if(APPLE)
add_custom_command(TARGET GSplus POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/rawnet/vmnet_helper"
"${CMAKE_CURRENT_BINARY_DIR}/GSplus.app/Contents/MacOS/vmnet_helper"
)
add_dependencies(GSplus vmnet_helper)
endif()
# SET_SOURCE_FILES_PROPERTIES(vmnet_helper PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
add_library(x_readline readline.c)
if (READLINE MATCHES "AUTO")
if (CMAKE_SYSTEM_NAME MATCHES "(Darwin|FreeBSD|OpenBSD|NetBSD)")
set(READLINE "LIBEDIT")
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(READLINE "READLINE")
endif()
endif()
if(READLINE MATCHES "READLINE")
target_compile_definitions(x_readline PRIVATE USE_READLINE)
target_link_libraries(x_readline PUBLIC readline)
elseif(READLINE MATCHES "LIBEDIT")
target_compile_definitions(x_readline PRIVATE USE_LIBEDIT)
target_link_libraries(x_readline PUBLIC edit)
endif()
target_link_libraries(GSplus x_readline)
if (WITH_RAWNET)
target_link_libraries(GSplus rawnet)
endif()
if (WITH_ATBRIDGE)
target_link_libraries(GSplus atbridge)
endif()
if (WIN32)
target_link_libraries(GSplus comdlg32 Shlwapi IPHlpApi
winmm gdi32 dsound comctl32 ws2_32 shell32
)
@ -165,26 +254,24 @@ if (DRIVER MATCHES "SDL")
endif()
if (APPLE)
target_link_libraries(GSplus "-framework Cocoa -framework vmnet")
target_link_libraries(GSplus "-framework Cocoa")
endif()
if (TOGGLE_STATUS)
target_compile_options(GSplus PUBLIC -DTOGGLE_STATUS)
target_compile_definitions(GSplus PUBLIC TOGGLE_STATUS)
endif()
if (WITH_DEBUGGER)
target_compile_definitions(GSplus PRIVATE GSPLUS_DEBUGGER)
endif()
#if (APPLE AND DRIVER MATCHES "SDL")
# target_compile_options(GSplus PRIVATE -F${CMAKE_CURRENT_SOURCE_DIR} )
# target_link_libraries(GSplus -F${CMAKE_CURRENT_SOURCE_DIR} "-framework SDL2" -Wl,-rpath,@executable_path/../Frameworks)
#endif()
# if (APPLE AND CMAKE_BUILD_TYPE MATCHES "Release")
# add_custom_command(TARGET GSplus
# POST_BUILD
# COMMAND dylibbundler -od -b -x GSplus.app/Contents/MacOS/GSplus -d GSplus.app/Contents/libs
# #COMMAND cp to_pro partls GSplus.app/Contents/Resources/
# COMMENT bundling libraries...
# )
# endif()
if (APPLE)
add_custom_target(bundle
@ -192,4 +279,9 @@ if (APPLE)
COMMAND dylibbundler -od -b -x GSplus.app/Contents/MacOS/GSplus -d GSplus.app/Contents/libs
COMMENT bundling libraries...
)
add_custom_target(setuid
COMMAND sudo chown root GSplus.app/Contents/MacOS/vmnet_helper
COMMAND sudo chmod +s GSplus.app/Contents/MacOS/vmnet_helper
USES_TERMINAL)
add_dependencies(setuid vmnet_helper)
endif()

View File

@ -1,196 +1,14 @@
# GSplus central makefile - you need a 'vars' file linked/copied from a 'vars_xxx' template to build.
#@todo: check for vars file and do something useful if missing :P
#@todo: remove all packaging junk and move to packaging scripts in CI
OBJECTS1 = adb.o clock.o config.o debug.o dis.o engine_c.o scc.o iwm.o \
joystick_driver.o moremem.o paddles.o parallel.o printer.o sim65816.o \
smartport.o sound.o sound_driver.o video.o scc_socket_driver.o glog.o \
imagewriter.o scc_imagewriter.o scc_llap.o options.o
ATOBJ = atbridge/aarp.o atbridge/atbridge.o atbridge/elap.o atbridge/llap.o atbridge/port.o
PCAPOBJ = atbridge/pcap_delay.o
TFEOBJ = tfe/tfe.o tfe/tfearch.o tfe/tfesupp.o
FSTOBJ = unix_host_common.o host_common.o host_fst.o host_mli.o
include vars
.PHONY: rtfm
rtfm:
@echo ""
@echo "CMAKE IS NOW USED AS THE BUILD SYSTEM"
@echo " (YES I'M YELLING)"
@echo ""
@echo "(from top level directory)"
@echo " mkdir build"
@echo " cd build"
@echo " cmake .."
@echo " make"
@echo ""
.SUFFIXES: .dep .proto
AS = $(CC)
XLIBS = -L/usr/X11R6/lib
PERL = perl
all: $(TARGET)
clean:
- rm -f $(OBJECTS)
- rm -f $(TARGET)
- rm -f compile_time.o
- rm -f 8inst_c.h
- rm -f 16inst_c.h
specials: 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s
specials_clean:
rm -f 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s
# Linux/OSX/RPi SDL builds
gsplus: $(OBJECTS) compile_time.o
$(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS)
echo $(OBJECTS)
cp gsplus ..
# Linux/OSX XWindows builds
gsplusx: $(OBJECTS) compile_time.o
$(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(XLIBS) $(EXTRA_LIBS) -lX11
echo $(OBJECTS)
mv gsplusx ..
# NOT CURRENTLY SUPPORTED
# Linux framebuffer builds:
gsplusfb: $(OBJECTS) compile_time.o
$(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS)
echo $(OBJECTS)
mv gsplusfb ..
# Mingw32 / Cygwin builds: The Win32 API version
gsplus32.exe: $(OBJECTS) compile_time.o
g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32
#mkdir -p ../GSplus.app/lib
#cp -f gsplus.exe ../GSplus.app/GSplus.exe
#cp -f ../config.template ../GSplus.app/config.txt
#cp -f ../lib/*.ttf ../GSplus.app/lib
#cp -f ../lib/arch/win32/*.dll ../GSplus.app
#cp -f ../lib/NoBoot.po ../GSplus.app
#cp -f GSplus.bat ../GSplus.app/GSplus.bat
#cp -f parallel.rom ../GSplus.app
#cp -f ../COPYING.txt ../GSplus.app
cp gsplus32.exe ..
# Mingw32 / Cygwin builds: The SDL version (builds, but non-functioning)
gsplus.exe: $(OBJECTS) compile_time.o
#g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32
#g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -mwindows
g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32
cp gsplus.exe ..
# NOT CURRENTLY SUPPORTED
# Mac build - old style (deprecated)
gsportmac: $(OBJECTS) compile_time.o
$(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o gsport $(EXTRA_LIBS)
mkdir -p ../GSport.app/Contents/Resources/English.lproj/main.nib
mkdir -p ../GSport.app/Contents/MacOS
mv gsport ../GSport.app/Contents/MacOS/GSport
echo "APPL????" > ../GSport.app/Contents/PkgInfo
cp -f arch/mac/Info.plist ../GSport.app/Contents/
cp -f arch/mac/info.nib ../GSport.app/Contents/Resources/English.lproj/main.nib
cp -f arch/mac/classes.nib ../GSport.app/Contents/Resources/English.lproj/main.nib
cp -f arch/mac/objects.xib ../GSport.app/Contents/Resources/English.lproj/main.nib
cp -f arch/mac/gsporticon.icns ../GSport.app/Contents/Resources/
cp -f arch/mac/525.icns ../GSport.app/Contents/Resources/
cp -f arch/mac/2mg.icns ../GSport.app/Contents/Resources/
touch '../GSport.app/Icon?'
rm -rf ../GSportDmg
mkdir ../GSportDmg
mkdir ../GSportDmg/GSport
cp ../COPYING.txt ../GSportDmg/GSport
cp -f parallel.rom ../GSportDmg/GSport
cp -f ../lib/NoBoot.po ../GSportDmg/GSport
mv ../GSport.app ../GSportDmg/GSport
cp -f ../config.template ../GSportDmg/GSport/config.txt
cp ../GSport.html ../GSportDmg/GSport/GSport.html
arch/mac/makedmg.sh .. GSportDmg GSport GSport 7
8inst_c.h: instable.h
$(PERL) make_inst c 8 instable.h > 8inst_c.h
16inst_c.h: instable.h
$(PERL) make_inst c 16 instable.h > 16inst_c.h
size_c.h: size_tab.h
$(PERL) make_size c size_tab.h > size_c.h
engine_c.o: 8inst_c.h 16inst_c.h size_c.h
8inst_s.h: instable.h
$(PERL) make_inst s 8 instable.h > 8inst_s.h
16inst_s.h: instable.h
$(PERL) make_inst s 16 instable.h > 16inst_s.h
size_s.h: size_tab.h
$(PERL) make_size s size_tab.h > size_s.h
8size_s.h: size_tab.h
$(PERL) make_size 8 size_tab.h > 8size_s.h
16size_s.h: size_tab.h
$(PERL) make_size 16 size_tab.h > 16size_s.h
engine_s.o: 8inst_s.h 16inst_s.h 8size_s.h 16size_s.h size_s.h
.s.o:
$(AS) -c $(OPTS) -I. $*.s
.c.o:
$(CC) $(CCOPTS) $(XOPTS) -c $(OPTS) -I. -o $*.o $*.c
.cpp.o:
$(CC) $(CPPOPTS) $(XOPTS) -c $(OPTS) -I. $*.cpp
.cpp.O:
$(CC) $(CCOPTS) $(XOPTS) -c $(OPTS) -I. $*.c
partls: partls.c
cc $(CCOPTS) $(XOPTS) $(OPTS) -o partls partls.c
to_pro: prodos.h prodos_protos.h to_pro.c
cc $(CCOPTS) $(XOPTS) $(OPTS) -o to_pro to_pro.c
gsplus32.o: win32.rc winresource.h
windres win32.rc -o gsplus32.o
compile_time.o: $(OBJECTS)
# dependency stuff
adb.o: adb.c adb.h defc.h defcomm.h iwm.h protos.h
atbridge/aarp.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/elap.h atbridge/aarp.h atbridge/elap_defs.h
atbridge/atbridge.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/elap.h atbridge/llap.h atbridge/aarp.h
atbridge/elap.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/elap.h atbridge/aarp.h atbridge/elap_defs.h atbridge/pcap_delay.h
atbridge/llap.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/llap.h
atbridge/port.o: atbridge/atalk.h atbridge/port.h
atbridge/pcap_delay.o: atbridge/pcap_delay.h
engine_c.o: engine_c.c defc.h defcomm.h iwm.h protos.h protos_engine_c.h size_c.h op_routs.h defs_instr.h 8inst_c.h 16inst_c.h
clock.o: clock.c defc.h defcomm.h iwm.h protos.h
compile_time.o: compile_time.c
config.o: config.c defc.h defcomm.h iwm.h protos.h config.h
dis.o: dis.c defc.h defcomm.h iwm.h protos.h disas.h
scc.o: scc.c defc.h defcomm.h iwm.h protos.h scc.h
scc_llap.o: atbridge/atbridge.h atbridge/llap.h defc.h scc.h
scc_socket_driver.o: scc_socket_driver.c defc.h defcomm.h iwm.h protos.h scc.h
scc_windriver.o: scc_windriver.c defc.h defcomm.h iwm.h protos.h scc.h
scc_macdriver.o: scc_macdriver.c defc.h defcomm.h iwm.h protos.h scc.h
scc_imagewriter.o: scc_imagewriter.c defc.h defcomm.h protos.h scc.h
iwm.o: iwm.c defc.h defcomm.h iwm.h protos.h iwm_35_525.h
imagewriter.o: imagewriter.cpp
joystick_driver.o: joystick_driver.c defc.h defcomm.h iwm.h protos.h
moremem.o: moremem.c defc.h defcomm.h iwm.h protos.h
paddles.o: paddles.c defc.h defcomm.h iwm.h protos.h
parallel.o: parallel.c defc.h
printer.o: printer.cpp
sim65816.o: sim65816.c defc.h defcomm.h iwm.h protos.h
smartport.o: smartport.c defc.h defcomm.h iwm.h protos.h
sound.o: sound.c defc.h defcomm.h iwm.h protos.h sound.h
sound_driver.o: sound_driver.c defc.h defcomm.h iwm.h protos.h sound.h
video.o: video.c defc.h defcomm.h iwm.h protos.h superhires.h gsportfont.h
tfe.o: tfe/tfe.c tfe/tfe.h tfe/tfe_protos.h
tfearch.o: tfe/tfearch.c tfe/tfearch.h tfe/tfe_protos.h
tfesupp.o: tfe/tfesupp.c tfe/tfesupp.h tfe/tfe_protos.h
macdriver.o: macdriver.c defc.h defcomm.h iwm.h protos.h protos_macdriver.h
macdriver_console.o: macdriver_console.c defc.h defcomm.h iwm.h protos.h protos_macdriver.h
macdriver_generic.o: macdriver_generic.c defc.h defcomm.h iwm.h protos.h protos_macdriver.h
macsnd_driver.o: macsnd_driver.c defc.h defcomm.h iwm.h protos.h sound.h
windriver.o: windriver.c defc.h defcomm.h iwm.h protos.h protos_windriver.h winresource.h gsplus32.o
win_console.o: win_console.c defc.h defcomm.h iwm.h protos.h protos_windriver.h winresource.h
win_generic.o: win_generic.c defc.h defcomm.h iwm.h protos.h protos_windriver.h winresource.h
win32snd_driver.o: win32snd_driver.c defc.h defcomm.h iwm.h protos.h sound.h

View File

@ -1,86 +0,0 @@
/*
* Copyright (C) 1999 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _BITTYPES_H
#define _BITTYPES_H
#ifndef HAVE_U_INT8_T
#if SIZEOF_CHAR == 1
typedef unsigned char u_int8_t;
typedef signed char int8_t;
#elif SIZEOF_INT == 1
typedef unsigned int u_int8_t;
typedef signed int int8_t;
#else /* XXX */
#error "there's no appropriate type for u_int8_t"
#endif
#define HAVE_U_INT8_T 1
#define HAVE_INT8_T 1
#endif /* HAVE_U_INT8_T */
#ifndef HAVE_U_INT16_T
#if SIZEOF_SHORT == 2
typedef unsigned short u_int16_t;
typedef signed short int16_t;
#elif SIZEOF_INT == 2
typedef unsigned int u_int16_t;
typedef signed int int16_t;
#elif SIZEOF_CHAR == 2
typedef unsigned char u_int16_t;
typedef signed char int16_t;
#else /* XXX */
#error "there's no appropriate type for u_int16_t"
#endif
#define HAVE_U_INT16_T 1
#define HAVE_INT16_T 1
#endif /* HAVE_U_INT16_T */
#ifndef HAVE_U_INT32_T
#if SIZEOF_INT == 4
typedef unsigned int u_int32_t;
typedef signed int int32_t;
#elif SIZEOF_LONG == 4
typedef unsigned long u_int32_t;
typedef signed long int32_t;
#elif SIZEOF_SHORT == 4
typedef unsigned short u_int32_t;
typedef signed short int32_t;
#else /* XXX */
#error "there's no appropriate type for u_int32_t"
#endif
#define HAVE_U_INT32_T 1
#define HAVE_INT32_T 1
#endif /* HAVE_U_INT32_T */
#endif /* _BITTYPES_H */

View File

@ -1,523 +0,0 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header$ (LBL)
*/
#ifndef BPF_MAJOR_VERSION
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _MSC_VER
#include <WinSock2.h>
typedef unsigned int u_int;
typedef unsigned char u_char;
typedef unsigned short u_short;
#endif
/* BSD style release date */
#define BPF_RELEASE 199606
typedef int bpf_int32;
typedef u_int bpf_u_int32;
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
#else
#define BPF_ALIGNMENT sizeof(long)
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32
/*
* Structure for BIOCSETF.
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct returned by BIOCGSTATS.
*/
struct bpf_stat {
u_int bs_recv; /* number of packets received */
u_int bs_drop; /* number of packets dropped */
};
/*
* Struct return by BIOCVERSION. This represents the version number of
* the filter language described by the instruction encodings below.
* bpf understands a program iff kernel_major == filter_major &&
* kernel_minor >= filter_minor, that is, if the value returned by the
* running kernel has the same major number and a minor number equal
* equal to or less than the filter being downloaded. Otherwise, the
* results are undefined, meaning an error may be returned or packets
* may be accepted haphazardly.
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/*
* BPF ioctls
*
* The first set is for compatibility with Sun's pcc style
* header files. If your using gcc, we assume that you
* have run fixincludes so the latter set should work.
*/
#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
#define BIOCGBLEN _IOR(B,102, u_int)
#define BIOCSBLEN _IOWR(B,102, u_int)
#define BIOCSETF _IOW(B,103, struct bpf_program)
#define BIOCFLUSH _IO(B,104)
#define BIOCPROMISC _IO(B,105)
#define BIOCGDLT _IOR(B,106, u_int)
#define BIOCGETIF _IOR(B,107, struct ifreq)
#define BIOCSETIF _IOW(B,108, struct ifreq)
#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW(B,112, u_int)
#define BIOCVERSION _IOR(B,113, struct bpf_version)
#define BIOCSTCPF _IOW(B,114, struct bpf_program)
#define BIOCSUDPF _IOW(B,115, struct bpf_program)
#else
#define BIOCGBLEN _IOR('B',102, u_int)
#define BIOCSBLEN _IOWR('B',102, u_int)
#define BIOCSETF _IOW('B',103, struct bpf_program)
#define BIOCFLUSH _IO('B',104)
#define BIOCPROMISC _IO('B',105)
#define BIOCGDLT _IOR('B',106, u_int)
#define BIOCGETIF _IOR('B',107, struct ifreq)
#define BIOCSETIF _IOW('B',108, struct ifreq)
#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW('B',112, u_int)
#define BIOCVERSION _IOR('B',113, struct bpf_version)
#define BIOCSTCPF _IOW('B',114, struct bpf_program)
#define BIOCSUDPF _IOW('B',115, struct bpf_program)
#endif
/*
* Structure prepended to each packet.
*/
struct bpf_hdr {
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};
/*
* Because the structure above is not a multiple of 4 bytes, some compilers
* will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
* Only the kernel needs to know about it; applications use bh_hdrlen.
*/
#if defined(KERNEL) || defined(_KERNEL)
#define SIZEOF_BPF_HDR 18
#endif
/*
* Data-link level type codes.
*/
/*
* These are the types that are the same on all platforms; on other
* platforms, a <net/bpf.h> should be supplied that defines the additional
* DLT_* codes appropriately for that platform (the BSDs, for example,
* should not just pick up this version of "bpf.h"; they should also define
* the additional DLT_* codes used by their kernels, as well as the values
* defined here - and, if the values they use for particular DLT_ types
* differ from those here, they should use their values, not the ones
* here).
*/
#define DLT_NULL 0 /* no link-layer encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* IEEE 802 Networks */
#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
/*
* These are values from the traditional libpcap "bpf.h".
* Ports of this to particular platforms should replace these definitions
* with the ones appropriate to that platform, if the values are
* different on that platform.
*/
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
/*
* These are values from BSD/OS's "bpf.h".
* These are not the same as the values from the traditional libpcap
* "bpf.h"; however, these values shouldn't be generated by any
* OS other than BSD/OS, so the correct values to use here are the
* BSD/OS values.
*
* Platforms that have already assigned these values to other
* DLT_ codes, however, should give these codes the values
* from that platform, so that programs that use these codes will
* continue to compile - even though they won't correctly read
* files of these types.
*/
#ifdef __NetBSD__
#ifndef DLT_SLIP_BSDOS
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
#endif
#else
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#endif
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
* These values are defined by NetBSD; other platforms should refrain from
* using them for other purposes, so that NetBSD savefiles with link
* types of 50 or 51 can be read as this type on all platforms.
*/
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
/*
* Values between 100 and 103 are used in capture file headers as
* link-layer types corresponding to DLT_ types that differ
* between platforms; don't use those values for new DLT_ new types.
*/
/*
* This value was defined by libpcap 0.5; platforms that have defined
* it with a different value should define it here with that value -
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
* whatever value that happens to be, so programs will correctly
* handle files with that link type regardless of the value of
* DLT_C_HDLC.
*
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
* compatibility with programs written for BSD/OS.
*
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
* for source compatibility with programs written for libpcap 0.5.
*/
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
/*
* 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
* except when it isn't. (I.e., sometimes it's just raw IP, and
* sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
* so that we don't have to worry about the link-layer header.)
*/
/*
* Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
* with other values.
* DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
* (DLCI, etc.).
*/
#define DLT_FRELAY 107
/*
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
* that the AF_ type in the link-layer header is in network byte order.
*
* OpenBSD defines it as 12, but that collides with DLT_RAW, so we
* define it as 108 here. If OpenBSD picks up this file, it should
* define DLT_LOOP as 12 in its version, as per the comment above -
* and should not use 108 as a DLT_ value.
*/
#define DLT_LOOP 108
/*
* Values between 109 and 112 are used in capture file headers as
* link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ types
* other than the corresponding DLT_ types.
*/
/*
* This is for Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
/*
* Apple LocalTalk hardware.
*/
#define DLT_LTALK 114
/*
* Acorn Econet.
*/
#define DLT_ECONET 115
/*
* Reserved for use with OpenBSD ipfilter.
*/
#define DLT_IPFILTER 116
/*
* Reserved for use in capture-file headers as a link-layer type
* corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD,
* but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it
* in capture-file headers.
*/
#define DLT_PFLOG 117
/*
* Registered for Cisco-internal use.
*/
#define DLT_CISCO_IOS 118
/*
* Reserved for 802.11 cards using the Prism II chips, with a link-layer
* header including Prism monitor mode information plus an 802.11
* header.
*/
#define DLT_PRISM_HEADER 119
/*
* Reserved for Aironet 802.11 cards, with an Aironet link-layer header
* (see Doug Ambrisko's FreeBSD patches).
*/
#define DLT_AIRONET_HEADER 120
/*
* Reserved for Siemens HiPath HDLC.
*/
#define DLT_HHDLC 121
/*
* This is for RFC 2625 IP-over-Fibre Channel.
*
* This is not for use with raw Fibre Channel, where the link-layer
* header starts with a Fibre Channel frame header; it's for IP-over-FC,
* where the link-layer header starts with an RFC 2625 Network_Header
* field.
*/
#define DLT_IP_OVER_FC 122
/*
* This is for Full Frontal ATM on Solaris with SunATM, with a
* pseudo-header followed by an AALn PDU.
*
* There may be other forms of Full Frontal ATM on other OSes,
* with different pseudo-headers.
*
* If ATM software returns a pseudo-header with VPI/VCI information
* (and, ideally, packet type information, e.g. signalling, ILMI,
* LANE, LLC-multiplexed traffic, etc.), it should not use
* DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
* and the like don't have to infer the presence or absence of a
* pseudo-header and the form of the pseudo-header.
*/
#define DLT_SUNATM 123 /* Solaris+SunATM */
/*
* Reserved as per request from Kent Dahlgren <kent@praesum.com>
* for private use.
*/
#define DLT_RIO 124 /* RapidIO */
#define DLT_PCI_EXP 125 /* PCI Express */
#define DLT_AURORA 126 /* Xilinx Aurora link layer */
/*
* For future use with 802.11 captures - defined by AbsoluteValue
* Systems to store a number of bits of link-layer information:
*
* http://www.shaftnet.org/~pizza/software/capturefrm.txt
*
* but could and arguably should also be used by non-AVS Linux
* 802.11 drivers and BSD drivers; that may happen in the future.
*/
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */
/*
* Reserved for the TZSP encapsulation, as per request from
* Chris Waters <chris.waters@networkchemistry.com>
* TZSP is a generic encapsulation for any other link type,
* which includes a means to include meta-information
* with the packet, e.g. signal strength and channel
* for 802.11 packets.
*/
#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */
/*
* BSD's ARCNET headers have the source host, destination host,
* and type at the beginning of the packet; that's what's handed
* up to userland via BPF.
*
* Linux's ARCNET headers, however, have a 2-byte offset field
* between the host IDs and the type; that's what's handed up
* to userland via PF_PACKET sockets.
*
* We therefore have to have separate DLT_ values for them.
*/
#define DLT_ARCNET_LINUX 129 /* ARCNET */
/*
* The instruction encodings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL))
/*
* Systems based on non-BSD kernels don't have ifnet's (or they don't mean
* anything if it is in <net/if.h>) and won't work like this.
*/
# if __STDC__
extern void bpf_tap(struct ifnet *, u_char *, u_int);
extern void bpf_mtap(struct ifnet *, struct mbuf *);
extern void bpfattach(struct ifnet *, u_int, u_int);
extern void bpfilterattach(int);
# else
extern void bpf_tap();
extern void bpf_mtap();
extern void bpfattach();
extern void bpfilterattach();
# endif /* __STDC__ */
#endif /* BSD && (_KERNEL || KERNEL) */
#if __STDC__ || defined(__cplusplus)
extern int bpf_validate(struct bpf_insn *, int);
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#else
extern int bpf_validate();
extern u_int bpf_filter();
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,159 +0,0 @@
/*
* Copyright (c) 1993, 1994, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header$ (LBL)
*/
/*
* This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows
*/
#include <winsock2.h>
#ifndef __MINGW32__
#include <ws2tcpip.h>
#endif /* __MINGW32__ */
#define IN_MULTICAST(a) IN_CLASSD(a)
#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xe0000000) == 0xe0000000)
#define IN_LOOPBACKNET 127
#ifdef __MINGW32__
/* IPv6 address */
struct in6_addr
{
union
{
u_int8_t u6_addr8[16];
u_int16_t u6_addr16[8];
u_int32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
#define s6_addr64 in6_u.u6_addr64
};
#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
#endif /* __MINGW32__ */
#ifdef __MINGW32__
typedef unsigned short sa_family_t;
#define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family
/* Ditto, for IPv6. */
struct sockaddr_in6
{
__SOCKADDR_COMMON (sin6_);
u_int16_t sin6_port; /* Transport layer port # */
u_int32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
};
#define IN6_IS_ADDR_V4MAPPED(a) \
((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
(((u_int32_t *) (a))[2] == htonl (0xffff)))
#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff)
#define IN6_IS_ADDR_LINKLOCAL(a) \
((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000))
#define IN6_IS_ADDR_LOOPBACK(a) \
(((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
#endif /* __MINGW32__ */
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
#define nd_rd_type nd_rd_hdr.icmp6_type
#define nd_rd_code nd_rd_hdr.icmp6_code
#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
/*
* IPV6 extension headers
*/
#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
#define IPPROTO_IPV6 41 /* IPv6 header. */
#define IPPROTO_ROUTING 43 /* IPv6 routing header */
#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
#define IPPROTO_ESP 50 /* encapsulating security payload */
#define IPPROTO_AH 51 /* authentication header */
#define IPPROTO_ICMPV6 58 /* ICMPv6 */
#define IPPROTO_NONE 59 /* IPv6 no next header */
#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */
#define IPV6_RTHDR_TYPE_0 0
/* Option types and related macros */
#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
#define IP6OPT_PADN 0x01 /* 00 0 00001 */
#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
#define IP6OPT_JUMBO_LEN 6
#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */
#define IP6OPT_RTALERT_LEN 4
#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
#define IP6OPT_MINLEN 2
#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */
#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */
#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */
#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */
#define IP6OPT_EID 0x8a /* 10 0 01010 */
#define IP6OPT_TYPE(o) ((o) & 0xC0)
#define IP6OPT_TYPE_SKIP 0x00
#define IP6OPT_TYPE_DISCARD 0x40
#define IP6OPT_TYPE_FORCEICMP 0x80
#define IP6OPT_TYPE_ICMP 0xC0
#define IP6OPT_MUTABLE 0x20
#ifdef __MINGW32__
#ifndef EAI_ADDRFAMILY
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for hostname */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
#endif
#endif /* __MINGW32__ */

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2002
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the Politecnico
* di Torino, and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header$ (LBL)
*/
#define SIZEOF_CHAR 1
#define SIZEOF_SHORT 2
#define SIZEOF_INT 4
#define _WINSOCKAPI_
#include <fcntl.h>
#include <winsock2.h>
#include "bittypes.h"
#include <time.h>
#include <io.h>
#ifndef __MINGW32__
#include "IP6_misc.h"
#endif
#define caddr_t char*
#define snprintf _snprintf
//#define vsnprintf _vsnprintf

View File

@ -1,273 +0,0 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header$ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
#include <sys/types.h>
#if defined _MSC_VER
# include <time.h>
#else
#include <sys/time.h>
#endif
/* RGJ Changed it to "bpf.h" for AppleWin */
#include "bpf.h"
#include <stdio.h>
#ifdef REMOTE
// We have to define the SOCKET here, although it has been defined in sockutils.h
// This is to avoid the distribution of the 'sockutils.h' file around
// (for example in the WinPcap developer's pack)
#ifndef SOCKET
#ifdef WIN32
#define SOCKET unsigned int
#else
#define SOCKET int
#endif
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
/*
* Compatibility for systems that have a bpf.h that
* predates the bpf typedefs for 64-bit support.
*/
#if BPF_RELEASE - 0 < 199406
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
typedef struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;
typedef struct pcap_if pcap_if_t;
typedef struct pcap_addr pcap_addr_t;
/*
* The first record in the file contains saved values for some
* of the flags used in the printout phases of tcpdump.
* Many fields here are 32 bit ints so compilers won't insert unwanted
* padding; these files need to be interchangeable across architectures.
*
* Do not change the layout of this structure, in any way (this includes
* changes that only affect the length of fields in this structure).
*
* Also, do not change the interpretation of any of the members of this
* structure, in any way (this includes using values other than
* LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
* field).
*
* Instead:
*
* introduce a new structure for the new format, if the layout
* of the structure changed;
*
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
* magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed file
* header;
*
* make the code in "savefile.c" capable of reading files with
* the old file header as well as files with the new file header
* (using the magic number to determine the header format).
*
* Then supply the changes to "patches@tcpdump.org", so that future
* versions of libpcap and programs that use it (such as tcpdump) will
* be able to read your new capture file format.
*/
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
* packet interfaces.
*/
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
/*
* As returned by the pcap_stats()
*/
struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
#ifdef REMOTE
#ifdef WIN32
// u_int bs_capt; /* number of packets that reach the application */
#endif /* WIN32 */
u_int ps_capt; /* number of packets that reach the application; please get rid off the Win32 ifdef */
u_int ps_sent; /* number of packets sent by the server on the network */
u_int ps_netdrop; /* number of packets lost on the network */
#endif
};
/*
* Item in a list of interfaces.
*/
struct pcap_if {
struct pcap_if *next;
char *name; /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
/*
* Representation of an interface address.
*/
struct pcap_addr {
struct pcap_addr *next;
struct sockaddr *addr; /* address */
struct sockaddr *netmask; /* netmask for that address */
struct sockaddr *broadaddr; /* broadcast address for that address */
struct sockaddr *dstaddr; /* P2P destination address for that address */
};
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
char *pcap_lookupdev(char *);
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);
void pcap_close(pcap_t *);
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr *);
int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
int pcap_getnonblock(pcap_t *, char *);
int pcap_setnonblock(pcap_t *, int, char *);
void pcap_perror(pcap_t *, char *);
char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
bpf_u_int32);
int pcap_compile_nopcap(int, int, struct bpf_program *,
char *, int, bpf_u_int32);
void pcap_freecode(struct bpf_program *);
int pcap_datalink(pcap_t *);
int pcap_list_datalinks(pcap_t *, int **);
int pcap_set_datalink(pcap_t *, int);
int pcap_datalink_name_to_val(const char *);
const char *pcap_datalink_val_to_name(int);
int pcap_snapshot(pcap_t *);
int pcap_is_swapped(pcap_t *);
int pcap_major_version(pcap_t *);
int pcap_minor_version(pcap_t *);
/* XXX */
FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
int pcap_dump_flush(pcap_dumper_t *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
/* To avoid callback, this returns one packet at a time */
int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data);
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
int bpf_validate(struct bpf_insn *f, int len);
char *bpf_image(struct bpf_insn *, int);
void bpf_dump(struct bpf_program *, int);
#ifdef WIN32
/*
* Win32 definitions
*/
int pcap_setbuff(pcap_t *p, int dim);
int pcap_setmode(pcap_t *p, int mode);
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
int pcap_setmintocopy(pcap_t *p, int size);
#ifdef WPCAP
/* Include file with the wpcap-specific extensions */
#include <Win32-Extensions.h>
#endif
#define MODE_CAPT 0
#define MODE_STAT 1
#define MODE_MON 2
#endif /* WIN32 */
#ifdef REMOTE
/* Includes most of the public stuff that is needed for the remote capture */
#include "remote-ext.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

2556
src/assets/GSBug.Templates Normal file

File diff suppressed because it is too large Load Diff

120
src/assets/GSOS.text Normal file
View File

@ -0,0 +1,120 @@
; ProDOS 16 Calls.
0001 CREATE
0002 DESTROY
0004 CHANGE_PATH
0005 SET_FILE_INFO
0006 GET_FILE_INFO
0008 VOLUME
0009 SET_PREFIX
000A GET_PREFIX
000B CLEAR_BACKUP_BIT
0010 OPEN
0011 NEWLINE
0012 READ
0013 WRITE
0014 CLOSE
0015 FLUSH
0016 SET_MARK
0017 GET_MARK
0018 SET_EOF
0019 GET_EOF
001A SET_LEVEL
001B GET_LEVEL
001C GET_DIR_ENTRY
0020 GET_DEV_NUM
0021 GET_LAST_DEV
0022 READ_BLOCK
0023 WRITE_BLOCK
0024 FORMAT
0025 ERASE_DISK
0027 GET_NAME
0028 GET_BOOT_VOL
0029 QUIT
002A GET_VERSION
002C D_INFO
0031 ALLOC_INTERRUPT
0032 DEALLOCATE_INTERRUPT
; ORCA/Shell calls.
0101 Get_LInfo
0102 Set_LInfo
0103 Get_Lang
0104 Set_Lang
0105 Error
0106 Set_Variable
0107 Version
0108 Read_Indexed
0109 Init_Wildcard
010A Next_Wildcard
010B Read_Variable
010C ChangeVector
010D Execute
010E FastFile
010F Direction
0110 Redirect
0113 Stop
0114 ExpandDevices
0115 UnsetVariable
0116 Export
0117 PopVariables
0118 PushVariables
0119 SetStopFlag
011A ConsoleOut
011B SetIODevices
011C GetIODevices
011D GetCommand
; GS/OS Calls.
2001 Create
2002 Destroy
2003 OSShutdown
2004 ChangePath
2005 SetFileInfo
2006 GetFileInfo
2007 JudgeName
2008 Volume
2009 SetPrefix
200A GetPrefix
200B ClearBackup
200C SetSysPrefs
200D Null
200E ExpandPath
200F GetSysPrefs
2010 Open
2011 NewLine
2012 Read
2013 Write
2014 Close
2015 Flush
2016 SetMark
2017 GetMark
2018 SetEOF
2019 GetEOF
201A SetLevel
201B GetLevel
201C GetDirEntry
201D BeginSession
201E EndSession
201F SessionStatus
2020 GetDevNumber
2024 Format
2025 EraseDisk
2026 ResetCache
2027 GetName
2028 GetBootvol
2029 Quit
202A GetVersion
202B GetFSTInfo
202C DInfo
202D DStatus
202E DControl
202F DRead
2030 DWrite
2031 BindInt
2032 UnbindInt
2033 FSTSpecific
2034 AddNotifyProc
2035 DelNotifyProc
2036 DRename
2037 GetStdRefNum
2038 GetRefNum
2039 GetRefInfo
203A SetStdRefNum

2653
src/assets/NList.Data Normal file

File diff suppressed because it is too large Load Diff

1460
src/assets/Tools.text Normal file

File diff suppressed because it is too large Load Diff

BIN
src/assets/gsp_icon.icns Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -3,3 +3,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(atbridge aarp.c atbridge.c elap.c llap.c pcap_delay.c port.c)
target_compile_definitions(atbridge PUBLIC HAVE_ATBRIDGE)
if(WIN32)
target_link_libraries(atbridge ws2_32) # winsock2
endif()

View File

@ -17,7 +17,7 @@
#include "aarp.h"
#ifdef WIN32
#include <winsock.h>
#include <winsock2.h>
#elif __linux__
#include <netinet/in.h>
#endif

View File

@ -18,7 +18,7 @@
#include "aarp.h"
#ifdef WIN32
#include <winsock.h>
#include <winsock2.h>
#elif __linux__
#include <netinet/in.h>
#endif

View File

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\arch\win32\pcap.h" />
<ClInclude Include="aarp.h" />
<ClInclude Include="atalk.h" />
<ClInclude Include="atbridge.h" />
<ClInclude Include="elap.h" />
<ClInclude Include="elap_defs.h" />
<ClInclude Include="llap.h" />
<ClInclude Include="pcap_delay.h" />
<ClInclude Include="port.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="aarp.c" />
<ClCompile Include="atbridge.c" />
<ClCompile Include="elap.c" />
<ClCompile Include="llap.c" />
<ClCompile Include="pcap_delay.c" />
<ClCompile Include="port.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>atbridge</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<CompileAs>Default</CompileAs>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,66 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="llap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="atbridge.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="elap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\arch\win32\pcap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="port.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="aarp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="elap_defs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="atalk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pcap_delay.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="llap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="atbridge.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="elap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="port.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="aarp.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pcap_delay.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -16,12 +16,12 @@
#include "elap_defs.h"
#include "pcap_delay.h"
#ifdef __CYGWIN__
#include <Windows.h>
#include <NspAPI.h>
#endif
// #ifdef __CYGWIN__
// #include <Windows.h>
// #include <NspAPI.h>
// #endif
#ifdef WIN32
#include <winsock.h>
#include <winsock2.h>
#include <IPHlpApi.h>
#endif
#ifdef __linux__

View File

@ -14,13 +14,7 @@ This wrapper provides a subset of the available PCAP APIs necessary for ATBridge
Feel free to extend the wrapper.
*/
#ifdef WIN32
#include "../arch/win32/pcap.h"
#elif __linux__
#include <pcap.h>
#elif __APPLE__
#include <pcap/pcap.h>
#endif
bool pcapdelay_load();
bool pcapdelay_is_loaded();

View File

@ -7,26 +7,40 @@
#include "defc.h"
#include <stdarg.h>
#include <ctype.h>
#include "config.h"
#include "glog.h"
#include "imagewriter.h"
#if defined(_MSC_VER)
#include "arch\win32\dirent-win32.h"
#else
#include <dirent.h>
#endif
#ifdef HAVE_TFE
#include "tfe/tfesupp.h"
#include "tfe/protos_tfe.h"
#include <dirent.h>
#ifdef HAVE_RAWNET
#include "rawnet/rawnet.h"
#endif
#if defined _MSC_VER
#include <direct.h>
#define snprintf _snprintf
typedef unsigned int mode_t;
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
#define KEY_DOWN_ARROW 0x0a
#define KEY_UP_ARROW 0x0b
#define KEY_RIGHT_ARROW 0x15
#define KEY_LEFT_ARROW 0x08
#define KEY_TAB 0x09
#define KEY_RETURN 0x0d
#define KEY_PAGE_DOWN 0x1079
#define KEY_PAGE_UP 0x1074
#define KEY_ESC 0x1b
#define KEY_DELETE 0x7f
static const char parse_log_prefix_file[] = "Option set [file]:";
@ -75,7 +89,8 @@ extern int g_joystick_button_0;
extern int g_joystick_button_1;
extern int g_joystick_button_2;
extern int g_joystick_button_3;
extern int g_ethernet;
extern int g_halt_on_bad_read;
extern int g_ignore_bad_acc;
extern int g_ignore_halts;
@ -100,7 +115,8 @@ extern int g_joystick_trim_amount_y;
extern int g_swap_paddles;
extern int g_invert_paddles;
extern int g_ethernet;
extern int g_ethernet_interface;
extern int g_ethernet_enabled;
extern char * g_ethernet_interface;
extern int g_appletalk_bridging;
extern int g_appletalk_turbo;
extern int g_appletalk_diagnostics;
@ -129,7 +145,7 @@ extern char* g_imagewriter_prop_font;
extern int g_imagewriter_paper;
extern int g_imagewriter_banner;
#if defined(_WIN32) && !defined(WIN_SDL) || defined(__CYGWIN__) && !defined(WIN_SDL)
#if defined(_WIN32) && !defined(HAVE_SDL)
extern int g_win_show_console_request;
extern int g_win_status_debug_request;
#endif
@ -199,6 +215,8 @@ int g_cfg_file_dir_only = 0;
#define MAX_PARTITION_BLK_SIZE 65536
void display_rawnet_menu(const char *name, const char **value);
extern Cfg_menu g_cfg_main_menu[];
#define KNMP(a) &a, #a, 0
@ -233,7 +251,6 @@ Cfg_menu g_cfg_uiless_menu[] = {
{ "", KNMP(g_joystick_button_1), CFGTYPE_INT },
{ "", KNMP(g_joystick_button_2), CFGTYPE_INT },
{ "", KNMP(g_joystick_button_3), CFGTYPE_INT },
{ "", KNMP(g_ethernet), CFGTYPE_INT },
{ "", KNMP(g_halt_on_bad_read), CFGTYPE_INT },
{ "", KNMP(g_ignore_bad_acc), CFGTYPE_INT },
{ "", KNMP(g_ignore_halts), CFGTYPE_INT },
@ -350,10 +367,11 @@ Cfg_menu g_cfg_parallel_menu[] = {
{ 0, 0, 0, 0, 0 },
};
#ifdef HAVE_RAWNET
Cfg_menu g_cfg_ethernet_menu[] = {
{ "Ethernet Card Configuration", g_cfg_ethernet_menu, 0, 0, CFGTYPE_MENU },
{ "Use Interface Number,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10",
KNMP(g_ethernet_interface), CFGTYPE_INT },
{ "Interface",
KNMP(g_ethernet_interface), CFGTYPE_STR_FUNC, display_rawnet_menu },
{ "", 0, 0, 0, 0 },
{ "Uthernet Card in Slot 3,0,Off,1,On",
KNMP(g_ethernet), CFGTYPE_INT },
@ -368,6 +386,8 @@ Cfg_menu g_cfg_ethernet_menu[] = {
{ "Back to Main Config", g_cfg_main_menu, 0, 0, CFGTYPE_MENU },
{ 0, 0, 0, 0, 0 },
};
#endif
#ifdef HAVE_SDL
Cfg_menu g_cfg_printer_menu[] = {
{ "Virtual Epson Configuration", g_cfg_printer_menu, 0, 0, CFGTYPE_MENU },
@ -428,7 +448,7 @@ Cfg_menu g_cfg_imagewriter_menu[] = {
Cfg_menu g_cfg_devel_menu[] = {
{ "Developer Options", g_cfg_devel_menu, 0, 0, CFGTYPE_MENU },
#if defined(_WIN32) && !defined(WIN_SDL) || defined(__CYGWIN__) && !defined(WIN_SDL)
#if defined(_WIN32) && !defined(HAVE_SDL)
{ "Status lines,0,Hide,1,Show", KNMP(g_win_status_debug_request), CFGTYPE_INT },
{ "Console,0,Hide,1,Show", KNMP(g_win_show_console_request), CFGTYPE_INT },
#endif
@ -457,7 +477,9 @@ Cfg_menu g_cfg_main_menu[] = {
{ "ROM File Selection", g_cfg_rom_menu, 0, 0, CFGTYPE_MENU },
{ "HOST FST Configuration", g_cfg_host_menu, 0, 0, CFGTYPE_MENU },
{ "Serial Port Configuration", g_cfg_serial_menu, 0, 0, CFGTYPE_MENU },
#ifdef HAVE_RAWNET
{ "Ethernet Card Configuration", g_cfg_ethernet_menu, 0, 0, CFGTYPE_MENU },
#endif
{ "Parallel Card Configuration", g_cfg_parallel_menu, 0, 0, CFGTYPE_MENU },
#ifdef HAVE_SDL
{ "Virtual Epson Configuration", g_cfg_printer_menu, 0, 0, CFGTYPE_MENU },
@ -469,15 +491,14 @@ Cfg_menu g_cfg_main_menu[] = {
{ "Expansion Mem Size,0,0MB,0x100000,1MB,0x200000,2MB,0x300000,3MB,"
"0x400000,4MB,0x600000,6MB,0x800000,8MB,0xa00000,10MB,0xc00000,12MB,"
"0xe00000,14MB", KNMP(g_mem_size_exp), CFGTYPE_INT },
{ "Dump text screen to file", (void *)cfg_text_screen_dump, 0, 0, CFGTYPE_FUNC},
{ "Dump text screen to file", 0, 0, 0, CFGTYPE_FUNC, cfg_text_screen_dump},
#ifdef HAVE_SDL
{ "Reset Virtual ImageWriter", (void *)cfg_iwreset, 0, 0, CFGTYPE_FUNC },
{ "Reset Virtual ImageWriter", 0, 0, 0, CFGTYPE_FUNC, cfg_iwreset },
#endif
{ "", 0, 0, 0, 0 },
{ "Save changes to configuration file", (void *)config_write_config_gsplus_file, 0, 0,
CFGTYPE_FUNC },
{ "Save changes to configuration file", 0, 0, 0, CFGTYPE_FUNC, config_write_config_gsplus_file },
{ "", 0, 0, 0, 0 },
{ "Exit Config (or press F4)", (void *)cfg_exit, 0, 0, CFGTYPE_FUNC },
{ "Exit Config (or press F4)", 0, 0, 0, CFGTYPE_FUNC, cfg_exit },
{ 0, 0, 0, 0, 0 },
};
@ -595,6 +616,7 @@ void config_init_menus(Cfg_menu *menuptr) {
case CFGTYPE_STR:
case CFGTYPE_FILE:
case CFGTYPE_DIR:
case CFGTYPE_STR_FUNC:
str_ptr = (char **)menuptr->ptr;
str = *str_ptr;
// We need to malloc this string since all
@ -695,36 +717,7 @@ void cfg_iwreset() {
imagewriter_init(g_imagewriter_dpi,g_imagewriter_paper,g_imagewriter_banner, g_imagewriter_output,g_imagewriter_multipage);
return;
}
#ifdef HAVE_TFE
void cfg_get_tfe_name() {
int i = 0;
char *ppname = NULL;
char *ppdes = NULL;
cfg_htab_vtab(0,11);
if (tfe_enumadapter_open())
{
cfg_printf("Interface List:\n---------------");
while(tfe_enumadapter(&ppname,&ppdes))
{
cfg_htab_vtab(0, 13+i);
cfg_printf("%2d: %s",i,ppdes);
i++;
lib_free(ppname);
lib_free(ppdes);
}
tfe_enumadapter_close();
}
else
{
#if defined(_WIN32) || defined(__CYGWIN__)
cfg_printf("ERROR: Install/Enable WinPcap for Ethernet Support!!");
#else
cfg_printf("ERROR: Install/Enable LibPcap for Ethernet Support!!");
#endif
}
return;
}
#endif
void config_vbl_update(int doit_3_persec) {
if(doit_3_persec) {
@ -810,6 +803,7 @@ void config_parse_option(char *buf, int pos, int len, int line) {
case CFGTYPE_STR:
case CFGTYPE_FILE:
case CFGTYPE_DIR:
case CFGTYPE_STR_FUNC:
strptr = (char **)menuptr->ptr;
if(strptr && *strptr) {
free(*strptr);
@ -1333,6 +1327,7 @@ void config_write_config_gsplus_file() {
case CFGTYPE_STR:
case CFGTYPE_FILE:
case CFGTYPE_DIR:
case CFGTYPE_STR_FUNC:
curstr = *((char **)menuptr->ptr);
defstr = *((char **)menuptr->defptr);
if(strcmp(curstr, defstr) != 0) {
@ -1421,7 +1416,7 @@ void insert_disk(int slot, int drive, const char *name, int ejected, int force_s
name_len = strlen(name);
name_ptr = (char *)malloc(name_len + 1);
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32)
// On Windows, we need to change backslashes to forward slashes.
for (i = 0; i < name_len; i++) {
if (name[i] == '\\') {
@ -2059,6 +2054,11 @@ void cfg_putchar(int c) {
g_cfg_curs_x = x;
}
void cfg_puts(const char *str, int nl) {
for(;*str; ++str) cfg_putchar(*str);
if (nl) cfg_putchar('\n');
}
void cfg_printf(const char *fmt, ...) {
va_list ap;
int c;
@ -2260,6 +2260,7 @@ void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int chan
case CFGTYPE_STR:
case CFGTYPE_FILE:
case CFGTYPE_DIR:
case CFGTYPE_STR_FUNC:
str_ptr = (char **)menuptr->ptr;
curstr = *str_ptr;
str_ptr = (char **)menuptr->defptr;
@ -2292,6 +2293,7 @@ void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int chan
case CFGTYPE_INT:
case CFGTYPE_FILE:
case CFGTYPE_DIR:
case CFGTYPE_STR_FUNC:
g_cfg_opt_buf[bufpos++] = ' ';
g_cfg_opt_buf[bufpos++] = '=';
g_cfg_opt_buf[bufpos++] = ' ';
@ -2371,6 +2373,7 @@ void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int chan
snprintf(str, CFG_OPT_MAXSTR, "%d", curval);
break;
case CFGTYPE_STR:
case CFGTYPE_STR_FUNC:
str = &(g_cfg_opts_strs[0][0]);
//printf("curstr is: %s str is: %s\n", curstr,str);
snprintf(str, CFG_OPT_MAXSTR, "%s", curstr);
@ -3068,16 +3071,14 @@ void cfg_file_handle_key(int key) {
listhdrptr = &g_cfg_partitionlist;
}
// can't hotkey numbers because it falsely matches PGUP/PGDN
if( (g_cfg_file_pathfield == 0) &&
((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z')) ) {
if( (g_cfg_file_pathfield == 0) && isalnum(key)) {
/* jump to file starting with this letter */
g_cfg_file_match[0] = key;
g_cfg_file_match[1] = 0;
g_cfg_dirlist.invalid = 1; /* re-read directory */
} else {
switch(key) {
case 0x1b:
case KEY_ESC:
if(g_cfg_slotdrive < 0xfff) {
eject_disk_by_num(g_cfg_slotdrive >> 8, g_cfg_slotdrive & 0xff);
}
@ -3085,41 +3086,41 @@ void cfg_file_handle_key(int key) {
g_cfg_select_partition = -1;
g_cfg_dirlist.invalid = 1;
break;
case 0x0a: /* down arrow */
case KEY_DOWN_ARROW: /* down arrow */
if(g_cfg_file_pathfield == 0) {
listhdrptr->curent++;
cfg_fix_topent(listhdrptr);
}
break;
case 0x0b: /* up arrow */
case KEY_UP_ARROW: /* up arrow */
if(g_cfg_file_pathfield == 0) {
listhdrptr->curent--;
cfg_fix_topent(listhdrptr);
}
break;
case 0x33: /* pg dn */
case KEY_PAGE_DOWN: /* pg dn */
if(g_cfg_file_pathfield == 0) {
listhdrptr->curent += CFG_PG_SCROLL_AMT;
cfg_fix_topent(listhdrptr);
}
break;
case 0x39: /* pg up */
case KEY_PAGE_UP: /* pg up */
if(g_cfg_file_pathfield == 0) {
listhdrptr->curent -= CFG_PG_SCROLL_AMT;
cfg_fix_topent(listhdrptr);
}
break;
case 0x0d: /* return */
case KEY_RETURN: /* return */
cfg_file_selected(0);
break;
case 0x09: /* tab */
case KEY_TAB: /* tab */
g_cfg_file_pathfield = !g_cfg_file_pathfield;
break;
case 0x15:
case KEY_RIGHT_ARROW:
glogf("You can't go right!"); /* eggs - DB */
break;
case 0x08: /* left arrow */
case 0x7f: /* delete key */
case KEY_LEFT_ARROW: /* left arrow */
case KEY_DELETE: /* delete key */
if(g_cfg_file_pathfield) {
len = strlen(&g_cfg_file_curpath[0]) - 1;
if(len >= 0) {
@ -3127,7 +3128,7 @@ void cfg_file_handle_key(int key) {
}
}
break;
case 0x20: /* space -- selects file/directory */
case ' ': /* space -- selects file/directory */
cfg_file_selected(g_cfg_file_dir_only);
break;
default:
@ -3136,18 +3137,57 @@ void cfg_file_handle_key(int key) {
}
}
void config_control_panel() {
void (*fn_ptr)();
static int config_read_key(void) {
int key = -1;
int mods;
while(g_config_control_panel & !(halt_sim&HALT_WANTTOQUIT)) {
video_update();
key = adb_read_c000();
if(key & 0x80) {
key = key & 0x7f;
mods = adb_read_c025();
(void)adb_access_c010();
//printf("key: %02x modifiers: %02x\n", key, mods);
// Fkeys have the keypad bit set (but so do numbers) */
if ((mods & 0x10) && key > 0x3f) key |= 0x1000;
return key;
}
micro_sleep(1.0/60.0);
g_cfg_vbl_count++;
}
return -1;
}
void config_display_file_menu(void) {
int key;
cfg_file_init();
while (g_cfg_slotdrive >= 0) {
cfg_file_draw();
cfg_htab_vtab(0, 23);
cfg_printf("Move: \tJ\t \tK\t Change: \tH\t \tU\t \tM");
if (g_cfg_slotdrive < 0xfff) cfg_printf("\t Eject: \bESC\b");
key = config_read_key();
if (key < 0) break;
cfg_file_handle_key(key);
}
}
void config_control_panel() {
const char *str;
Cfg_menu *menuptr;
void *ptr;
int print_eject_help;
void *cookie;
int line;
int type;
int match_found;
int menu_line;
int menu_inc;
int max_line;
int min_line;
int key;
int i, j;
// First, save important text screen state
@ -3188,10 +3228,38 @@ void config_control_panel() {
}
cfg_home();
line = 1;
max_line = 1;
match_found = 0;
print_eject_help = 0;
cfg_printf("%s\n\n", menuptr[0].str);
/* calc max/min items */
max_line = 0;
min_line = 0;
for (i = 0;;++i) {
const char *cp = menuptr[i].str;
if (!cp) break;
if (!*cp) continue; /* place holder */
if (!min_line) min_line = i;
max_line = i;
}
/* menu advancement */
if (menu_inc > 0) {
if (menu_line > max_line) menu_line = max_line;
for( ; menu_line < max_line; ++menu_line) {
const char *cp = menuptr[menu_line].str;
if (*cp) break;
}
menu_inc = 0;
}
if (menu_inc < 0) {
if (menu_line < min_line) menu_line = min_line;
for( ; menu_line > min_line; --menu_line) {
const char *cp = menuptr[menu_line].str;
if (*cp) break;
}
menu_inc = 0;
}
while(line < 24) {
str = menuptr[line].str;
type = menuptr[line].cfgtype;
@ -3199,44 +3267,22 @@ void config_control_panel() {
if(str == 0) {
break;
}
if((type & 0xf) == CFGTYPE_DISK) {
print_eject_help = 1;
}
cfg_parse_menu(menuptr, line, menu_line, 0);
if(line == menu_line) {
if(type != 0) {
match_found = 1;
} else if(menu_inc) {
menu_line++;
} else {
menu_line--;
}
}
if(line > max_line) {
max_line = line;
}
cfg_printf("%s\n", g_cfg_opt_buf);
line++;
}
if((menu_line < 1) && !match_found) {
menu_line = 1;
}
if((menu_line >= max_line) && !match_found) {
menu_line = max_line;
}
if(g_rom_version < 0) {
cfg_htab_vtab(0, 21);
cfg_printf("\bYOU MUST SELECT A VALID ROM FILE\b\n");
}
cfg_htab_vtab(0, 23);
cfg_printf("Move: \tJ\t \tK\t Change: \tH\t \tU\t \tM\t");
if(print_eject_help) {
cfg_printf(" Eject: ");
if(g_cfg_slotdrive >= 0) {
cfg_printf("\bESC\b");
} else {
cfg_printf("E");
}
cfg_printf("Move: \tJ\t \tK\t Change: \tH\t \tU\t \tM");
type = menuptr[menu_line].cfgtype;
if ((type & 0x0f) == CFGTYPE_DISK) {
cfg_printf("\t Eject: E");
}
#if 0
cfg_htab_vtab(0, 22);
@ -3244,126 +3290,111 @@ void config_control_panel() {
menu_line, line, g_cfg_vbl_count, g_adb_repeat_vbl,
g_key_down);
#endif
if(g_cfg_slotdrive >= 0) {
cfg_file_draw();
}
#ifdef HAVE_TFE
/*HACK eh, at least I think it is. Display the available ethernet interfaces
when in the ethernet control panel. This is the only way one can customize a menu pane.
Kent did it with the directory browser, so why not.*/
if(menuptr == g_cfg_ethernet_menu)
{
cfg_get_tfe_name();
}
#ifdef HAVE_RAWNET
#endif
key = config_read_key();
if (key < 0) break;
// Normal menu system
switch(key) {
case KEY_DOWN_ARROW: /* down arrow */
if (menu_line < max_line) menu_line++;
menu_inc = 1;
break;
case KEY_UP_ARROW: /* up arrow */
if (menu_line > 1) --menu_line;
menu_inc = -1;
break;
case KEY_PAGE_DOWN: /* pg dn */
menu_line += CFG_PG_SCROLL_AMT;
menu_inc = 1;
break;
case KEY_PAGE_UP: /* pg up */
menu_line -= CFG_PG_SCROLL_AMT;
menu_inc = -1;
break;
case KEY_RIGHT_ARROW: /* right arrow */
cfg_parse_menu(menuptr, menu_line,menu_line,1);
break;
case KEY_LEFT_ARROW: /* left arrow */
cfg_parse_menu(menuptr,menu_line,menu_line,-1);
break;
case KEY_RETURN:
type = menuptr[menu_line].cfgtype;
ptr = menuptr[menu_line].ptr;
str = menuptr[menu_line].str;
cookie = menuptr[menu_line].cookie;
switch(type & 0xf) {
case CFGTYPE_MENU:
menuptr = (Cfg_menu *)ptr;
menu_line = 1;
#ifdef HAVE_SDL
/*If user enters the Virtual Imagewriter control panel, flag it so we can
automatically apply changes on exit.*/
if(menuptr == g_cfg_imagewriter_menu)
{
g_cfg_triggeriwreset = 1;
}
/*If user enters the Virtual Imagewriter control panel, flag it so we can
automatically apply changes on exit.*/
if(menuptr == g_cfg_imagewriter_menu) {
g_cfg_triggeriwreset = 1;
}
#endif
key = -1;
while(g_config_control_panel & !(halt_sim&HALT_WANTTOQUIT)) {
video_update();
key = adb_read_c000();
if(key & 0x80) {
key = key & 0x7f;
(void)adb_access_c010();
break;
case CFGTYPE_FUNC: {
void (*fn)(void);
fn = (void (*)(void))cookie;
if (fn) fn();
adb_all_keys_up(); //Needed otherwise menu function will continue to repeat until we move selection up or down
break;
}
case CFGTYPE_DISK:
g_cfg_slotdrive = type >> 4;
g_cfg_file_dir_only = 0;
config_display_file_menu();
break;
case CFGTYPE_FILE:
g_cfg_slotdrive = 0xfff;
g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr
g_cfg_file_strptr = (char **)ptr;
g_cfg_file_dir_only = 0;
config_display_file_menu();
break;
case CFGTYPE_DIR:
g_cfg_slotdrive = 0xfff;
g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr
g_cfg_file_strptr = (char **)ptr;
g_cfg_file_dir_only = 1;
config_display_file_menu();
break;
case CFGTYPE_STR_FUNC: {
void (*fn)(const char *, char **);
fn = (void (*)(const char *, char **))cookie;
if (fn) fn(str, (char **)ptr);
adb_all_keys_up();
break;
}
}
break;
} else {
key = -1;
}
micro_sleep(1.0/60.0);
g_cfg_vbl_count++;
if(!match_found) {
case KEY_ESC:
// Jump to last menu entry
menu_line = max_line;
break;
}
}
if((key >= 0) && (g_cfg_slotdrive < 0)) {
// Normal menu system
switch(key) {
case 0x0a: /* down arrow */
menu_line++;
menu_inc = 1;
break;
case 0x0b: /* up arrow */
menu_line--;
menu_inc = 0;
if(menu_line < 1) {
menu_line = 1;
}
break;
case 0x33: /* pg dn */
menu_line += CFG_PG_SCROLL_AMT;
menu_inc = 1;
break;
case 0x39: /* pg up */
menu_line -= CFG_PG_SCROLL_AMT;
menu_inc = 0;
if(menu_line < 1) {
menu_line = 1;
}
break;
case 0x15: /* right arrow */
cfg_parse_menu(menuptr, menu_line,menu_line,1);
break;
case 0x08: /* left arrow */
cfg_parse_menu(menuptr,menu_line,menu_line,-1);
break;
case 0x0d:
type = menuptr[menu_line].cfgtype;
ptr = menuptr[menu_line].ptr;
str = menuptr[menu_line].str;
switch(type & 0xf) {
case CFGTYPE_MENU:
menuptr = (Cfg_menu *)ptr;
menu_line = 1;
break;
case CFGTYPE_DISK:
g_cfg_slotdrive = type >> 4;
g_cfg_file_dir_only = 0;
cfg_file_init();
break;
case CFGTYPE_FUNC:
fn_ptr = (void (*)())ptr;
(*fn_ptr)();
adb_all_keys_up(); //Needed otherwise menu function will continue to repeat until we move selection up or down
break;
case CFGTYPE_FILE:
g_cfg_slotdrive = 0xfff;
g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr
g_cfg_file_strptr = (char **)ptr;
g_cfg_file_dir_only = 0;
cfg_file_init();
break;
case CFGTYPE_DIR:
g_cfg_slotdrive = 0xfff;
g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr
g_cfg_file_strptr = (char **)ptr;
g_cfg_file_dir_only = 1;
cfg_file_init();
break;
}
break;
case 0x1b:
// Jump to last menu entry
menu_line = max_line;
break;
case 'e':
case 'E':
type = menuptr[menu_line].cfgtype;
if((type & 0xf) == CFGTYPE_DISK) {
eject_disk_by_num(type >> 12,
(type >> 4) & 0xff);
}
break;
default:
glogf("Unhandled config key: 0x%02x", key);
}
} else if(key >= 0) {
cfg_file_handle_key(key);
case 'e':
case 'E':
type = menuptr[menu_line].cfgtype;
if((type & 0xf) == CFGTYPE_DISK) {
eject_disk_by_num(type >> 12,
(type >> 4) & 0xff);
}
break;
default:
glogf("Unhandled config key: 0x%02x", key);
}
}
for(i = 0; i < 0x400; i++) {
@ -3391,3 +3422,113 @@ void x_clk_setup_bram_version() {
g_bram_ptr = (&g_bram[1][0]); // ROM 03
}
}
#ifdef HAVE_RAWNET
void display_rawnet_menu(const char *name, const char **value) {
char *entries[20];
int i;
int index = -1;
int count = 0;
char *ppname = NULL;
char *ppdes = NULL;
memset(entries, 0, sizeof(entries));
if (rawnet_enumadapter_open()) {
count = 0;
while(rawnet_enumadapter(&ppname,&ppdes)) {
entries[count] = ppname;
free(ppdes);
if (index < 0 && !strcmp(*value, ppname)) index = count;
++count;
if (count == 20) break;
}
rawnet_enumadapter_close();
}
if (index < 0) index = 0;
for(;;) {
int key;
cfg_home();
cfg_puts(name, 1);
for (i = 0; i < 20; ++i) {
char *cp = entries[i];
if (!cp) break;
cfg_htab_vtab(4, i + 2);
if (i == index) cfg_putchar('\b'); /* inverse */
cfg_puts(cp, 1);
if (i == index) cfg_putchar('\b');
}
cfg_htab_vtab(0, 23);
cfg_puts("Move: \tJ\t \tK\t Change: \tM",1);
key = config_read_key();
switch(key) {
case KEY_UP_ARROW:
if (index) --index;
break;
case KEY_DOWN_ARROW:
if (index < count - 1) ++index;
break;
case KEY_PAGE_UP:
index -= CFG_PG_SCROLL_AMT;
if (index < 0) index = 0;
break;
case KEY_PAGE_DOWN:
index += CFG_PG_SCROLL_AMT;
if (index >= count) index = count - 1;
break;
case KEY_RETURN:
if (index < count) {
*value = strdup(entries[index]);
}
key = -1;
break;
case KEY_ESC:
key = -1;
break;
}
if (key < 0) break;
}
for (i = 0; i < 20; ++i) free(entries[i]);
}
void cfg_get_tfe_name() {
int i = 0;
char *ppname = NULL;
char *ppdes = NULL;
cfg_htab_vtab(0,11);
if (rawnet_enumadapter_open())
{
cfg_printf("Interface List:\n---------------");
while(rawnet_enumadapter(&ppname,&ppdes))
{
cfg_htab_vtab(0, 13+i);
cfg_printf("%2d: %s",i,ppdes);
i++;
free(ppname);
free(ppdes);
}
rawnet_enumadapter_close();
}
else
{
#if defined(_WIN32)
cfg_printf("ERROR: Install/Enable WinPcap for Ethernet Support!!");
#else
cfg_printf("ERROR: Install/Enable LibPcap for Ethernet Support!!");
#endif
}
return;
}
#endif

View File

@ -12,12 +12,13 @@
#define CFG_NUM_SHOWENTS 16
#define CFGTYPE_MENU 1
#define CFGTYPE_INT 2
#define CFGTYPE_INT 2
#define CFGTYPE_DISK 3
#define CFGTYPE_FUNC 4
#define CFGTYPE_FILE 5
#define CFGTYPE_STR 6
#define CFGTYPE_DIR 7
#define CFGTYPE_STR_FUNC 8
/* CFGTYPE limited to just 4 bits: 0-15 */
/* Cfg_menu, Cfg_dirent and Cfg_listhdr are defined in defc.h */

View File

@ -20,24 +20,18 @@
#include "glog.h"
// DISASSEMBLER STUFF
enum {
ABS = 1, ABSX, ABSY, ABSLONG, ABSIND, ABSXIND, IMPLY, ACCUM, IMMED, JUST8,
DLOC, DLOCX, DLOCY, LONG, LONGX, DLOCIND, DLOCINDY, DLOCXIND, DLOCBRAK,
DLOCBRAKY, DISP8, DISP8S, DISP8SINDY, DISP16, MVPMVN, REPVAL, SEPVAL
};
extern const char * const disas_opcodes[256];
extern const word32 disas_types[256];
#include "disasm.h"
// STEPPING/ENGINE STUFF
extern Engine_reg engine;
extern int g_config_control_panel;
extern int g_num_breakpoints;
extern word32 g_breakpts[MAX_BREAK_POINTS];
int g_dbg_enable_port = 0;
int debug_pause = 0;
int g_dbg_step = 0;
int step_count = 0;
extern int g_stepping;
// emulator command stuff
extern int g_limit_speed;
extern int g_screenshot_requested;
@ -223,9 +217,11 @@ void debug_handle_event() {
} else {
g_dbg_step = -1; // first one just halts
}
g_stepping = 1;
break;
case G_DBG_COMMAND_CONTINUE: //4
g_dbg_step = 0;
g_stepping = 0;
step_count = 0;
break;
case G_DBG_COMMAND_GET_MEM: //6
@ -238,7 +234,7 @@ void debug_handle_event() {
exit(0); // HALT!
break;
case G_DBG_COMMAND_DEBUGGER:
do_debug_intfc();
//do_debug_intfc();
break;
case G_DBG_COMMAND_SET_CPU:
event_set_cpu(&dbg_cmd_queue[0].cdata);
@ -278,7 +274,7 @@ void push_api_msg(int size, char *msg_str) {
void api_push_memack() {
int size = snprintf(tmp_buffer_4k, sizeof(tmp_buffer_4k),"{\"type\":\"memack\"}");
char *msg = (char*)malloc(sizeof(char) * size);
char *msg = (char*)malloc(sizeof(char) * size + 1);
strcpy(msg,tmp_buffer_4k);
push_api_msg(size, msg);
}
@ -309,13 +305,16 @@ void api_push_cpu() {
void api_push_brk() {
int i;
extern int g_num_bp_breakpoints;
extern word32 g_bp_breakpoints[];
// build our json array of breakpoints
tmp_buffer2_4k[0] = '\0'; // start with empty string
char *str_ptr = tmp_buffer2_4k;
for(i = 0; i < g_num_breakpoints; i++) {
for(i = 0; i < g_num_bp_breakpoints; i++) {
//printf("{\"bp:%02x: %06x\n", i, g_breakpts[i]);
str_ptr += sprintf(str_ptr, "{\"trig\":\"addr\",\"match\":\"%06X\"}", g_breakpts[i]);
if (i < g_num_breakpoints-1) {
str_ptr += sprintf(str_ptr, "{\"trig\":\"addr\",\"match\":\"%06X\"}", g_bp_breakpoints[i]);
if (i < g_num_bp_breakpoints-1) {
str_ptr += sprintf(str_ptr, ",");
}
}
@ -352,7 +351,7 @@ void api_push_stack() {
int size = snprintf(tmp_buffer_4k, sizeof(tmp_buffer_4k),"{\"type\":\"stack\",\"data\":{\"loc\":\"%06X\",\"S\":\"%04X\",\"bytes\":[%s]}}",
stack_loc,stack,str_ptr);
char *msg = (char*)malloc(sizeof(char) * size);
char *msg = (char*)malloc(sizeof(char) * size + 1);
strcpy(msg,tmp_buffer_4k);
push_api_msg(size, msg);
}
@ -360,7 +359,7 @@ void api_push_stack() {
void api_push_disassembly_start() {
int size = snprintf(tmp_buffer_4k, sizeof(tmp_buffer_4k),"{\"type\":\"dis0\"}");
char *msg = (char*)malloc(sizeof(char) * size);
char *msg = (char*)malloc(sizeof(char) * size + 1);
strcpy(msg,tmp_buffer_4k);
push_api_msg(size, msg);
}
@ -609,7 +608,7 @@ void event_add_brk(char *str) {
int addr = 0;
sscanf(str, "%06X", &addr);
addr = addr & 0xFFFFFF; // 24 bit KPC address for 65816
set_bp(addr);
set_bp('B', addr);
api_push_brk();
api_write_socket();
@ -621,7 +620,7 @@ void event_del_brk(char *str) {
int addr = 0;
sscanf(str, "%06X", &addr);
addr = addr & 0xFFFFFF; // 24 bit KPC address for 65816
delete_bp(addr);
delete_bp('B', addr);
api_push_brk();
api_write_socket();
@ -1217,8 +1216,8 @@ int do_dis_json(char *buf, word32 kpc, int accsize, int xsize, int op_provided,
kpc++;
dtype = disas_types[opcode];
out = disas_opcodes[opcode];
dtype = disasm_types[opcode];
out = disasm_opcodes[opcode];
type = dtype & 0xff;
args = dtype >> 8;
@ -1292,6 +1291,12 @@ int do_dis_json(char *buf, word32 kpc, int accsize, int xsize, int op_provided,
}
sprintf(buf_disasm,"%s $%06x",out,val);
break;
case ABSLONGX:
if(args != 3) {
printf("arg # mismatch for opcode %x\n", opcode);
}
sprintf(buf_disasm,"%s $%06x,X",out,val);
break;
case ABSIND:
if(args != 2) {
printf("arg # mismatch for opcode %x\n", opcode);
@ -1349,18 +1354,6 @@ int do_dis_json(char *buf, word32 kpc, int accsize, int xsize, int op_provided,
}
sprintf(buf_disasm,"%s $%02x,Y",out,val);
break;
case LONG:
if(args != 3) {
printf("arg # mismatch for opcode %x\n", opcode);
}
sprintf(buf_disasm,"%s $%06x",out,val);
break;
case LONGX:
if(args != 3) {
printf("arg # mismatch for opcode %x\n", opcode);
}
sprintf(buf_disasm,"%s $%06x,X",out,val);
break;
case DLOCIND:
if(args != 1) {
printf("arg # mismatch for opcode %x\n", opcode);

1891
src/debug_shell.re2c Normal file

File diff suppressed because it is too large Load Diff

400
src/debug_sweet16.re2c Normal file
View File

@ -0,0 +1,400 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "defc.h"
enum modes {
none = 0,
reg = 1 << 1,
indir_reg = 1 << 2,
reg_imm = 1 << 3,
relative = 1 << 4
};
static word32 to_hex(const char *iter, const char *end) {
word32 rv = 0;
while(iter != end) {
char c = *iter++;
rv <<= 4;
if (isdigit(c)) rv |= c - '0';
else rv |= (c | 0x20) - 'a' + 10;
}
return rv;
}
const char *ltrim(const char *cp) {
while (isspace(*cp)) ++cp;
return cp;
}
/*!re2c
re2c:define:YYCTYPE = char;
re2c:yyfill:enable = 0;
eol = "\x00";
ws = [ \t];
x = [A-Fa-f0-9];
*/
const char *parse_pc(const char *cp, uint32_t *pc) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
if (isspace(*cp)) return ltrim(cp);
/*!re2c
* { return NULL; }
x{4} ':' {
*pc &= 0xff0000;
*pc |= to_hex(cp, YYCURSOR - 1);
goto next;
}
x{6} ':' {
*pc = to_hex(cp, YYCURSOR - 1);
goto next;
}
x{2} '/' x{4} ':' {
uint32_t tmp = to_hex(cp, cp + 2) << 16;
tmp |= to_hex(cp + 3, YYCURSOR - 1);
*pc = tmp;
goto next;
}
*/
next:
return ltrim(YYCURSOR);
}
const char *parse_opcode(const char *cp, int *opcode, int *mode) {
int op = -1;
int m = 0;
unsigned c;
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
/* TODO - db, dw ? */
/*!re2c
* { return NULL; }
'set' { op = 0x10; m = reg_imm; goto next; }
'ld' { op = 0x20; m = reg | indir_reg; goto next; }
'st' { op = 0x30; m = reg | indir_reg; goto next; }
'ldd' { op = 0x60; m = indir_reg; goto next; }
'std' { op = 0x70; m = indir_reg; goto next; }
'pop' { op = 0x80; m = indir_reg; goto next; }
'stp' { op = 0x90; m = indir_reg; goto next; }
'add' { op = 0xa0; m = reg; goto next; }
'sub' { op = 0xb0; m = reg; goto next; }
'popd' { op = 0xc0; m = indir_reg; goto next; }
'cpr' { op = 0xd0; m = reg; goto next; }
'inr' { op = 0xe0; m = reg; goto next; }
'dcr' { op = 0xf0; m = reg; goto next; }
'rtn' { op = 0x00; goto next; }
'br' { op = 0x01; m = relative; goto next; }
'bnc' { op = 0x02; m = relative; goto next; }
'bc' { op = 0x03; m = relative; goto next; }
'bp' { op = 0x04; m = relative; goto next; }
'bm' { op = 0x05; m = relative; goto next; }
'bz' { op = 0x06; m = relative; goto next; }
'bnz' { op = 0x07; m = relative; goto next; }
'bm1' { op = 0x08; m = relative; goto next; }
'bnm1' { op = 0x09; m = relative; goto next; }
'bk' { op = 0x0a; goto next; }
'rs' { op = 0x0b; goto next; }
'bs' { op = 0x0c; m = relative; goto next; }
*/
next:
c = *YYCURSOR;
if (c && !isspace(c)) return NULL;
*opcode = op;
*mode = m;
return ltrim(YYCURSOR);
}
const char *parse_register(const char *cp, int *opcode) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
/*!re2c
* { return NULL; }
'R' ([0-9]{1,2}) {
int r = 0;
for(cp = cp + 1; cp < YYCURSOR; ++cp) {
r = r * 10 + *cp - '0';
}
if (r > 15) return NULL;
*opcode |= r;
goto next;
}
/*
'R' x {
int r = to_hex(cp + 1, YYCURSOR);
*opcode |= r;
goto next;
}
*/
'ACC' { *opcode |= 0x00; goto next; }
'PC' { *opcode |= 0x0f; goto next; }
'SR' { *opcode |= 0x0e; goto next; }
*/
next:
return ltrim(YYCURSOR);
}
const char *parse_address(const char *cp, int *address, int pc) {
const char *YYCURSOR = cp;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
int ea = 0;
/*!re2c
* { return NULL; }
'*' { ea = pc; goto next; }
'*' [+-] x{1,4} {
ea = to_hex(cp + 2, YYCURSOR);
if (cp[1] == '+') ea += pc;
else ea -= pc;
goto next;
}
x{1,4} {
ea = to_hex(cp, YYCURSOR);
goto next;
}
*/
next:
*address = ea & 0xffff;
return ltrim(YYCURSOR);
}
uint32_t sweet16_disasm(uint32_t addr, int lines) {
unsigned op;
const char *opcode;
unsigned mode = none;
unsigned operand;
unsigned x;
int i;
uint8_t bytes[4];
while (lines--) {
unsigned size = 0;
uint32_t pc = addr;
op = get_memory_c(addr++, 0);
bytes[size++] = op;
switch (op >> 4) {
case 0x00:
switch(op) {
case 0x00: opcode = "RTN"; break;
case 0x01: opcode = "BR"; mode = relative; break;
case 0x02: opcode = "BNC"; mode = relative; break;
case 0x03: opcode = "BC"; mode = relative; break;
case 0x04: opcode = "BP"; mode = relative; break;
case 0x05: opcode = "BM"; mode = relative; break;
case 0x06: opcode = "BZ"; mode = relative; break;
case 0x07: opcode = "BNZ"; mode = relative; break;
case 0x08: opcode = "BM1"; mode = relative; break;
case 0x09: opcode = "BNM1"; mode = relative; break;
case 0x0a: opcode = "BK"; break;
case 0x0b: opcode = "RS"; break;
case 0x0c: opcode = "BS"; mode = relative; break;
case 0x0d: opcode = "???"; break;
case 0x0e: opcode = "???"; break;
case 0x0f: opcode = "???"; break;
}
break;
case 0x01: opcode = "SET"; mode = reg_imm; break;
case 0x02: opcode = "LD"; mode = reg; break;
case 0x03: opcode = "ST"; mode = reg; break;
case 0x04: opcode = "LD"; mode = indir_reg; break;
case 0x05: opcode = "ST"; mode = indir_reg; break;
case 0x06: opcode = "LDD"; mode = indir_reg; break;
case 0x07: opcode = "STD"; mode = indir_reg; break;
case 0x08: opcode = "POP"; mode = indir_reg; break;
case 0x09: opcode = "STP"; mode = indir_reg; break;
case 0x0a: opcode = "ADD"; mode = reg; break;
case 0x0b: opcode = "SUB"; mode = reg; break;
case 0x0c: opcode = "POPD"; mode = indir_reg; break;
case 0x0d: opcode = "CPR"; mode = reg; break;
case 0x0e: opcode = "INR"; mode = reg; break;
case 0x0f: opcode = "DCR"; mode = reg; break;
}
switch(mode) {
case none:
case reg:
case indir_reg:
break;
case relative:
operand = (int8_t)get_memory_c(addr++, 0);
bytes[size++] = operand;
operand += addr;
operand &= 0xffff;
break;
case reg_imm:
operand = get_memory16_c(addr, 0);
addr += 2;
bytes[size++] = operand & 0xff;
bytes[size++] = operand >> 8;
break;
}
x = printf("%02x/%04x:", pc >> 16, pc & 0xffff);
for (i = 0; i < size; ++i) {
x += printf(" %02x", bytes[i]);
}
for( ; x < 20; ++x) fputc(' ', stdout);
printf("%-5s", opcode);
switch(mode) {
case none: break;
case reg: x += printf("R%d", op & 0x0f); break;
case indir_reg: x += printf("@R%d", op & 0x0f); break;
case relative:
x += printf("%04x", operand);
break;
case reg_imm:
x += printf("R%d, %04x", op & 0x0f, operand);
break;
}
fputc('\n', stdout);
}
return addr;
}
static int error(int offset, const char *msg) {
while (offset > 0) { fputc(' ', stderr); --offset; }
fputs(" ^", stderr);
fputs(msg, stderr);
fputc('\n', stderr);
return -1;
}
int parse_line(const char *cp, uint32_t *pc) {
uint32_t addr = *pc;
int opcode;
int operand;
int indir = 0;
int mode = 0;
int i;
unsigned offset = 0;
const char *start = cp;
uint8_t bytes[3];
int size = 0;
cp = parse_pc(cp, &addr);
if (!cp) return error(0, "error");
offset = cp - start;
/* label only? */
if (!*cp) {
*pc = addr;
return 0;
}
cp = parse_opcode(cp, &opcode, &mode);
if (!cp) return error(offset, "bad opcode");
offset = cp - start;
if (mode & (reg | indir_reg | reg_imm)) {
if (*cp == '@') {
indir = 1;
++cp;
}
cp = parse_register(cp, &opcode);
if (!cp) return error(offset, "bad register");
offset = cp - start;
/* cleanup indir */
/* LD / ST */
if (indir && mode == (reg|indir_reg)) {
opcode += 0x20;
mode = indir_reg;
}
if ((mode == indir_reg) != indir)
return error(offset, "bad operand");
}
bytes[size++] = opcode;
if (mode == reg_imm) {
if (*cp++ != ',')
return error(offset, "expected ,");
cp = ltrim(cp);
offset = cp - start;
}
if (mode & (relative | reg_imm)) {
cp = parse_address(cp, &operand, addr);
if (!cp) return error(offset, "bad operand");
offset = cp - start;
if (mode == relative) {
int tmp = (addr + 2) & 0xffff;
operand -= tmp;
if (operand > 127 || operand < -128)
return error(offset, "out of range");
bytes[size++] = operand;
} else {
bytes[size++] = operand & 0xff;
bytes[size++] = operand >> 8;
}
}
if (!cp) return error(offset, "bad operand");
for (i = 0; i < size; ++i) {
set_memory_c(addr + i, bytes[i], 0);
}
*pc = addr + size;
fputs("\r\x1b[A\x1b[K", stdout);
sweet16_disasm(addr, 1);
return 1;
}
extern char *x_readline(const char *prompt);
uint32_t sweet16_asm_shell(uint32_t addr) {
for(;;) {
const char *cp = x_readline("!!");
if (!cp || !*cp) return addr;
parse_line(cp, &addr);
}
}

577
src/debug_template.re2c Normal file
View File

@ -0,0 +1,577 @@
/*
*
* Load and parse GSBug templates and Nifty List Data.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "defc.h"
#ifdef WIN32
char *strndup(const char *s, size_t maxlen) {
char *cp;
size_t l = strlen(s);
if (l > maxlen) l = maxlen;
cp = malloc(l + 1);
if (cp) {
memcpy(cp, s, l);
cp[l] = 0;
}
return cp;
}
#endif
/*!re2c
re2c:define:YYCTYPE = char;
re2c:define:YYCURSOR = cp;
re2c:yyfill:enable = 0;
eol = "\x00";
ws = [ \t\r\n];
x = [0-9a-fA-F];
*/
/* format
_START name
name [type [size]] *
_END
*/
struct field {
char *name;
int type;
int count;
};
struct record {
char *name;
int total_size; /* total size */
int field_count; /* # of fields */
int field_index; /* starting index into the fields array */
};
static struct record *records = NULL;
static int record_count = 0;
static int record_alloc = 0;
static struct field *fields = NULL;
static int field_count = 0;
static int field_alloc = 0;
static int record_compare(const void *a, const void *b) {
const struct record *aa = a;
const struct record *bb = b;
int rv;
rv = strcasecmp(aa->name, bb->name);
//if (rv == 0) return aa->total_size - bb->total_size;
return rv;
}
/* 192 records in the standard file... */
static void add_record(struct record *r) {
/* calc size and count */
int i;
r->field_count = field_count - r->field_index;
for (i = r->field_index; i < field_count; ++i) {
int size = fields[i].type;
if (size > 4) size = 4;
r->total_size += size * fields[i].count;
}
if (record_count == record_alloc) {
size_t size = (record_alloc + 256) * sizeof(struct record);
void *tmp = realloc(records, size);
if (!tmp) return; /* oops */
records = tmp;
record_alloc += 256;
}
records[record_count++] = *r;
}
/* average ~14 fields per record */
static void add_field(struct field *f) {
if (field_count == field_alloc) {
size_t size = (field_alloc + 512) * sizeof(struct field);
void *tmp = realloc(fields, size);
if (!tmp) return; /* oops */
fields = tmp;
field_alloc += 512;
}
fields[field_count++] = *f;
}
static char *rtrim(char *cp) {
int l = strlen(cp);
while (l && isspace(cp[l-1])) --l;
cp[l] = 0;
return cp;
}
static char *ltrim(char *cp) {
while (isspace(*cp)) ++cp;
return cp;
}
/* 0 - no field, 1 - ok, -1 - warning */
static int parse_field(const char *cp, struct field *f) {
const char *start;
const char *end;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
int type = 0;
int count = 0;
start = cp;
for(;;) {
/*!re2c
eol | ws { --cp; break; }
* { continue; }
*/
}
end = cp;
if (start == end) return 0;
f->name = strndup(start, end - start);
f->type = 0;
f->count = 0;
while (isspace(*cp)) ++cp;
/* optional type */
/*!re2c
"BYTE" / (ws | eol) { type = 1; goto next; }
"WORD" / (ws | eol) { type = 2; goto next; }
"LONG" / (ws | eol) { type = 4; goto next; }
"CSTRING" / (ws | eol) { type = 5; goto next; }
"PSTRING" / (ws | eol) { type = 6; goto next; }
"GSSTRING" / (ws | eol) { type = 7; goto next; }
"" { type = 0; goto next; }
*/
next:
while (isspace(*cp)) ++cp;
if (type) {
count = 0;
while(isdigit(*cp)) {
count = count * 10 + *cp - '0';
++cp;
}
if (!count) count = 1;
}
while (isspace(*cp)) ++cp;
if (*cp != 0) {
return -1;
}
f->type = type;
f->count = count;
return 1;
}
void debug_load_templates(const char *path) {
FILE *f;
char buffer[1024];
int ok;
int in_struct = 0;
struct record record;
struct field field;
unsigned line = 0;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
f = fopen(path, "r");
if (!f) {
fprintf(stderr, "Unable to load %s: %s\n", path, strerror(errno));
return;
}
for (line = 1;;++line) {
const char *start = NULL;
const char *end = NULL;
const char *cp = fgets(buffer, sizeof(buffer), f);
if (!cp) break;
rtrim(buffer);
/*!re2c
"" { goto _field; }
";" { continue; }
ws* eol { continue; }
"_END" / (ws | eol) { goto _end; }
"_START" / (ws | eol) { goto _start; }
*/
_field:
if (!in_struct) {
/* warn once */
fprintf(stderr, "%s:%d: Missing _START.\n", path, line);
memset(&record, 0, sizeof(record));
in_struct = -1;
}
if (in_struct < 0) continue;
memset(&field, 0, sizeof(field));
ok = parse_field(cp, &field);
if (ok == 0) continue;
if (ok < 1) {
/* warn but add */
fprintf(stderr, "%s:%d: Bad field line: %s\n", path, line, buffer);
}
add_field(&field);
continue;
_start:
if (in_struct) {
/* warn and close it */
if (in_struct > 0) add_record(&record);
}
memset(&record, 0, sizeof(record));
while (isspace(*cp)) ++cp;
start = cp;
for(;;) {
/*!re2c
eol | ws { --cp; break; }
* { continue; }
*/
}
end = cp;
if (start == end) {
/* warning ... */
fprintf(stderr, "%s:%d: _START missing name.\n", path, line);
in_struct = -1;
} else {
in_struct = 1;
record.name = strndup(start, end - start);
record.field_index = field_count;
}
while (isspace(*cp)) ++cp;
if (*cp != 0) {
/* warning */
fprintf(stderr, "%s:%d: Bad _START line: %s\n", path, line, buffer);
}
continue;
_end:
while (isspace(*cp)) ++cp;
if (*cp != 0) {
/* warning ... */
fprintf(stderr, "%s:%d: Bad _END line: %s\n", path, line, buffer);
}
if (in_struct) {
if (in_struct > 0) add_record(&record);
} else {
/* warning */
fprintf(stderr, "%s:%d: _END without _START.\n", path, line);
}
in_struct = 0;
memset(&record, 0, sizeof(record));
continue;
}
if (in_struct) {
/* warn & close */
fprintf(stderr, "%s:%d: Missing _END.\n", path, line);
if (in_struct > 0) add_record(&record);
}
fclose(f);
qsort(records, record_count, sizeof(struct record), record_compare);
}
static int record_search(const void *a, const void *b) {
const struct record *r = b;
return strcasecmp(a, r->name);
}
static void print_string(int type, word32 address) {
unsigned c;
unsigned length;
unsigned more = 0;
if (!address) return;
fputc('"', stdout);
switch(type) {
case 5:
length = 32;
break;
case 6:
length = get_memory_c(address, 0);
++address;
break;
case 7:
length = get_memory16_c(address, 0);
address += 2;
break;
}
if (length > 32) {
length = 32;
more = 1;
}
for (unsigned i = 0; i < length; ++i) {
c = get_memory_c(address++, 0);
if (type == 5 && c == 0) break;
if ((~c & 0x80) && isprint(c)) {
fputc(c, stdout);
} else fprintf(stdout, "\\x%02x", c);
}
if (type == 5 && c != 0) more = 1;
if (more) fputs("...", stdout);
fputc('"', stdout);
fputc(' ', stdout);
}
word32 debug_apply_template(word32 address, const char *name) {
/* 1 - lookup template */
struct record *r;
int i, j;
struct field *f;
r = bsearch(name, records, record_count, sizeof(struct record), record_search);
if (r == NULL) {
fprintf(stderr, "Invalid template: %s\n", name);
return address;
}
f = fields + r->field_index;
if (r->total_size == 0) {
/* just print the fields */
for (i = 0; i < r->field_count; ++i) {
fputs(f[i].name, stdout);
fputc('\n', stdout);
}
fputc('\n', stdout);
return address;
}
for (i = 0; i < r->field_count; ++i) {
word32 value;
unsigned type = f[i].type;
printf("%-16s", f[i].name);
for (j = 0; j < f[i].count; ++j) {
switch(type) {
case 1:
value = get_memory_c(address, 0);
address += 1;
printf("%02x ", value);
break;
case 2:
value = get_memory16_c(address, 0);
address += 2;
printf("%04x ", value);
break;
case 4:
case 5: /* cstring */
case 6: /* pstring */
case 7: /* gs/os string */
value = get_memory24_c(address, 0);
address += 4;
printf("%08x ", value);
if (type > 4) {
print_string(type, value);
}
break;
}
address &= 0xffffff;
}
fputc('\n', stdout);
}
fputc('\n', stdout);
return address;
}
struct tool {
char *name;
unsigned number;
unsigned vector;
};
struct tool *tools = NULL;
int tool_count = 0;
int tool_alloc = 0;
static void add_tool(struct tool *t) {
if (tool_count == tool_alloc) {
size_t size = (tool_alloc + 1024) * sizeof(struct tool);
void *tmp = realloc(tools, size);
if (!tmp) return;
tools = tmp;
tool_alloc += 1024;
}
tools[tool_count++] = *t;
}
static word32 to_hex(const char *iter, const char *end) {
word32 rv = 0;
while(iter != end) {
char c = *iter++;
rv <<= 4;
if (isdigit(c)) rv |= c - '0';
else rv |= (c | 0x20) - 'a' + 10;
}
return rv;
}
static int tool_compare(const void *a, const void *b) {
const struct tool *aa = a;
const struct tool *bb = b;
int rv = (int)aa->vector - (int)bb->vector;
if (rv == 0)
rv = (int)aa->number - (int)bb->number;
return rv;
}
/* nifty list */
/*
* format:
* fffx ... header comments
* xxxx name ; p8 mli calls
* *
* xxxx name ; p16/gsos calls
* *
* xxxx name ; tool calls
* *
* xxxx name ; user tool calls
* *
* xxxx name ; e1 vectors
* *
* xxxx name ; e0 vectors
* *
* xxxx name ; softswitch/f8 rom
* *
* xxxx name ; 01 vectors
* *
* xxxx name ; nifty list service calls
* *
* xxxx name ; resource types
* *
* xxxx name ; error codes
* *
* xxxx name ; HC IIgs callbacks
* *
* xxxx name ; request codes
* *
*
*/
void debug_load_nifty(const char *path) {
FILE *f;
char buffer[1024];
unsigned line = 0;
const char *YYMARKER = NULL;
const char *YYCTXMARKER = NULL;
int section = 0;
unsigned vector = 0;
static unsigned vectors[] = {
0xbf00, 0xe100a8, 0xe10000, 0xe10008, 0xe1, 0xe0, 0xff, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00
};
f = fopen(path, "r");
if (!f) {
fprintf(stderr, "Unable to load %s: %s\n", path, strerror(errno));
return;
}
for (line = 1;;++line) {
const char *start;
const char *end;
struct tool tool = { 0, 0, vector };
const char *cp = fgets(buffer, sizeof(buffer), f);
if (!cp) break;
rtrim(buffer);
start = cp;
/*!re2c
[\r\n\x00] { continue; }
* {
fprintf(stderr, "%s:%d: Bad line: %s", path, line, buffer);
continue;
}
"*" {
++section;
vector = 0;
if (section < sizeof(vectors) / sizeof(vectors[0]))
vector = vectors[section];
continue;
}
x{4} / ws { goto ok; }
*/
ok:
end = cp;
tool.number = to_hex(start, end);
if (section == 0 && tool.number >= 0xfff0) continue;
if (!vector) continue;
while (isspace(*cp)) ++cp;
/* skip p8/p16/ prefix */
/*!re2c
"P8:" | "P16:" | "Shell:" | "GS/OS:" { goto prefix; }
"" { goto prefix; }
*/
prefix:
start = cp;
for(;;) {
/*!re2c
"" / eol { break; }
"(" | ws {
if (vector > 0x100 ) {
--cp;
break;
}
continue;
}
* { continue; }
*/
}
end = cp;
if (end > start) {
int l = end - start;
if (vector > 0x0100) {
/* add a leading _ */
tool.name = malloc(l + 2);
tool.name[0] = '_';
strncpy(tool.name + 1, start, l);
tool.name[l + 1] = 0;
}
else tool.name = strndup(start, l);
add_tool(&tool);
}
}
qsort(tools, tool_count, sizeof(struct tool), tool_compare);
fclose(f);
}
const char *debug_tool_name(unsigned number, unsigned vector) {
struct tool tmp = { 0, number, vector };
struct tool *t = bsearch(&tmp, tools, tool_count, sizeof(struct tool), tool_compare);
if (t) return t->name;
return NULL;
}

View File

@ -43,11 +43,13 @@ void U_STACK_TRACE();
#ifdef GSPLUS_LITTLE_ENDIAN
// @todo: look at using <byteswap.h> for fastest platform implementations
# define BIGEND(a) ((((a) >> 24) & 0xff) + \
(((a) >> 8) & 0xff00) + \
(((a) << 8) & 0xff0000) + \
(((a) << 24) & 0xff000000))
# define GET_BE_WORD16(a) ((((a) >> 8) & 0xff) + (((a) << 8) & 0xff00))
# define BIGEND(a) (\
(((a) >> 24) & 0xff) + \
(((a) >> 8) & 0xff00) + \
(((a) & 0xff00) << 8) + \
(((a) & 0xff ) << 24) \
)
# define GET_BE_WORD16(a) ((((a) >> 8) & 0xff) + ((((a) & 0xff) << 8)))
# define GET_BE_WORD32(a) (BIGEND(a))
#else
# define BIGEND(a) (a)
@ -151,6 +153,7 @@ STRUCT(Fplus) {
};
STRUCT(Engine_reg) {
Fplus *fplus_ptr;
double fcycles;
word32 kpc;
word32 acc;
@ -163,7 +166,7 @@ STRUCT(Engine_reg) {
word32 direct;
word32 psr;
Fplus *fplus_ptr;
word32 flags;
};
STRUCT(Kimage) {
@ -189,6 +192,7 @@ STRUCT(Cfg_menu) {
const char *name_str;
void *defptr;
int cfgtype;
void *cookie;
};
STRUCT(Cfg_dirent) {

View File

@ -49,17 +49,21 @@
#define BANK_BAD_MEM (&g_dummy_memory1_ptr[0xff])
#define ENGINE_FCYCLES 0x00
#define ENGINE_REG_KPC 0x08
#define ENGINE_REG_ACC 0x0c
#define ENGINE_REG_XREG 0x10
#define ENGINE_REG_YREG 0x14
#define ENGINE_REG_STACK 0x18
#define ENGINE_REG_DBANK 0x1c
#define ENGINE_REG_DIRECT 0x20
#define ENGINE_REG_PSR 0x24
#define ENGINE_FPLUS_PTR 0x28
/*
* this is only relevant for the PA RISC asm.
*
*/
#define ENGINE_FPLUS_PTR 0x00
#define ENGINE_FCYCLES 0x08
#define ENGINE_REG_KPC 0x10
#define ENGINE_REG_ACC 0x14
#define ENGINE_REG_XREG 0x18
#define ENGINE_REG_YREG 0x1c
#define ENGINE_REG_STACK 0x20
#define ENGINE_REG_DBANK 0x24
#define ENGINE_REG_DIRECT 0x28
#define ENGINE_REG_PSR 0x2c
#define ENGINE_FLAGS 0x30
#define LOG_PC_DCYCS 0x00
#define LOG_PC_DBANK_KPC 0x08
@ -77,20 +81,29 @@
#define FPLUS_PLUS_3 0x10
#define FPLUS_PLUS_X_M1 0x18
#define RET_BREAK 0x1
#define RET_BRK 0x1
#define RET_COP 0x2
#define RET_WDM 0x3
#define RET_MVP 0x4
#define RET_MVN 0x5
#define RET_WAI 0x6
#define RET_STP 0x7
#define RET_ADD_DEC_8 0x8
#define RET_ADD_DEC_16 0x9
#define RET_HALT 0x8
#define RET_C700 0xa
#define RET_C70A 0xb
#define RET_C70D 0xc
#define RET_IRQ 0xd
#define RET_BP 0xe
#define RET_MP 0xf
#define FLAG_IGNORE_MP 0x01
#define FLAG_IGNORE_BP 0x02
#define FLAG_STEP 0x04
#define FLAG_WANT_BRK 0x08
#define FLAG_WANT_COP 0x10
#define FLAG_WANT_RET 0x20
#define FLAG_WANT_JSL 0x40
#define FLAG_IGNORE_BRK 0x80 /* and cop */
#define MODE_BORDER 0
#define MODE_TEXT 1

View File

@ -1055,14 +1055,14 @@ defs_instr_start_16 .word 0
# define TSB_INST(in_bank) \
tmp1 = arg | acc; \
CYCLES_PLUS_1; \
zero = arg & acc; \
SET_MEMORY8(addr_latch, tmp1);
SET_MEMORY8(addr_latch, tmp1); \
zero = arg & acc;
# else
# define TSB_INST(in_bank) \
tmp1 = arg | acc; \
CYCLES_PLUS_1; \
zero = arg & acc; \
SET_MEMORY16(addr_latch, tmp1, in_bank);
SET_MEMORY16(addr_latch, tmp1, in_bank); \
zero = arg & acc;
# endif
#endif
@ -1107,15 +1107,15 @@ defs_instr_start_16 .word 0
psr = (psr & 0x1fe) + ((arg >> 7) & 1); \
tmp1 = (arg << 1) & 0xff; \
CYCLES_PLUS_1; \
SET_NEG_ZERO8(tmp1); \
SET_MEMORY8(addr_latch, tmp1);
SET_MEMORY8(addr_latch, tmp1); \
SET_NEG_ZERO8(tmp1);
# else
# define ASL_INST(in_bank) \
psr = (psr & 0x1fe) + ((arg >> 15) & 1);\
tmp1 = (arg << 1) & 0xffff; \
CYCLES_PLUS_1; \
SET_NEG_ZERO16(tmp1); \
SET_MEMORY16(addr_latch, tmp1, in_bank);
SET_MEMORY16(addr_latch, tmp1, in_bank);\
SET_NEG_ZERO16(tmp1);
# endif
#endif
@ -1302,14 +1302,14 @@ defs_instr_start_16 .word 0
arg = arg & 0xff; \
tmp1 = arg & ~acc; \
CYCLES_PLUS_1; \
zero = arg & acc; \
SET_MEMORY8(addr_latch, tmp1);
SET_MEMORY8(addr_latch, tmp1); \
zero = arg & acc;
# else
# define TRB_INST(in_bank) \
tmp1 = arg & ~acc; \
CYCLES_PLUS_1; \
zero = arg & acc; \
SET_MEMORY16(addr_latch, tmp1, in_bank);
SET_MEMORY16(addr_latch, tmp1, in_bank);\
zero = arg & acc;
# endif
#endif

1125
src/dis.c

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,7 @@
/*
GSPLUS - Advanced Apple IIGS Emulator Environment
Based on the KEGS emulator written by Kent Dickey
See COPYRIGHT.txt for Copyright information
See LICENSE.txt for license (GPL v2)
*/
enum {
ABS = 1,
ABSX,
ABSY,
ABSLONG,
ABSIND,
ABSXIND,
IMPLY,
ACCUM,
IMMED,
JUST8,
DLOC,
DLOCX,
DLOCY,
LONG,
LONGX,
DLOCIND,
DLOCINDY,
DLOCXIND,
DLOCBRAK,
DLOCBRAKY,
DISP8,
DISP8S,
DISP8SINDY,
DISP16,
MVPMVN,
REPVAL,
SEPVAL
};
#include "disasm.h"
const char * const disas_opcodes[256] = {
const char * const disasm_opcodes[256] = {
"BRK", "ORA", "COP", "ORA", "TSB", "ORA", "ASL", "ORA", /* 00-07 */
"PHP", "ORA", "ASL", "PHD", "TSB", "ORA", "ASL", "ORA", /* 08-0f */
"BPL", "ORA", "ORA", "ORA", "TRB", "ORA", "ASL", "ORA", /* 10-17 */
@ -72,7 +37,7 @@ const char * const disas_opcodes[256] = {
};
const word32 disas_types[256] = {
const unsigned disasm_types[256] = {
JUST8+0x100, DLOCXIND+0x100, /* 00-01 */
JUST8+0x100, DISP8S+0x100, /* 02-03 */
DLOC+0x100, DLOC+0x100, /* 04-05 */
@ -80,7 +45,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* 08-9 */
ACCUM+0x000, IMPLY+0x000, /* 0a-b */
ABS+0x200, ABS+0x200, /* c-d */
ABS+0x200, LONG+0x300, /* e-f */
ABS+0x200, ABSLONG+0x300, /* e-f */
DISP8+0x100, DLOCINDY+0x100, /* 10-11 */
DLOCIND+0x100, DISP8SINDY+0x100, /* 12-13 */
DLOC+0x100, DLOCX+0x100, /* 14-15 */
@ -88,7 +53,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, ABSY+0x200, /* 18-19 */
ACCUM+0x000, IMPLY+0x000, /* 1a-1b */
ABS+0x200, ABSX+0x200, /* 1c-1d */
ABSX+0x200, LONGX+0x300, /* 1e-1f */
ABSX+0x200, ABSLONGX+0x300, /* 1e-1f */
ABS+0x200, DLOCXIND+0x100, /* 20-21 */
ABSLONG+0x300, DISP8S+0x100, /* 22-23 */
DLOC+0x100, DLOC+0x100, /* 24-25 */
@ -96,7 +61,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* 28-29 */
ACCUM+0x000, IMPLY+0x000, /* 2a-2b */
ABS+0x200, ABS+0x200, /* 2c-2d */
ABS+0x200, LONG+0x300, /* 2e-2f */
ABS+0x200, ABSLONG+0x300, /* 2e-2f */
DISP8+0x100, DLOCINDY+0x100, /* 30-31 */
DLOCIND+0x100, DISP8SINDY+0x100, /* 32-33 */
DLOCX+0x100, DLOCX+0x100, /* 34-35 */
@ -104,7 +69,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, ABSY+0x200, /* 38-39 */
ACCUM+0x000, IMPLY+0x000, /* 3a-3b */
ABSX+0x200, ABSX+0x200, /* 3c-3d */
ABSX+0x200, LONGX+0x300, /* 3e-3f */
ABSX+0x200, ABSLONGX+0x300, /* 3e-3f */
IMPLY+0x000, DLOCXIND+0x100, /* 40-41 */
JUST8+0x100, DISP8S+0x100, /* 42-43 */
MVPMVN+0x200, DLOC+0x100, /* 44-45 */
@ -112,15 +77,15 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* 48-49 */
ACCUM+0x000, IMPLY+0x000, /* 4a-4b */
ABS+0x200, ABS+0x200, /* 4c-4d */
ABS+0x200, LONG+0x300, /* 4e-4f */
ABS+0x200, ABSLONG+0x300, /* 4e-4f */
DISP8+0x100, DLOCINDY+0x100, /* 50-51 */
DLOCIND+0x100, DISP8SINDY+0x100, /* 52-53 */
MVPMVN+0x200, DLOCX+0x100, /* 54-55 */
DLOCX+0x100, DLOCBRAKY+0x100, /* 56-57 */
IMPLY+0x000, ABSY+0x200, /* 58-59 */
IMPLY+0x000, IMPLY+0x000, /* 5a-5b */
LONG+0x300, ABSX+0x200, /* 5c-5d */
ABSX+0x200, LONGX+0x300, /* 5e-5f */
ABSLONG+0x300, ABSX+0x200, /* 5c-5d */
ABSX+0x200, ABSLONGX+0x300, /* 5e-5f */
IMPLY+0x000, DLOCXIND+0x100, /* 60-61 */
DISP16+0x200, DISP8S+0x100, /* 62-63 */
DLOC+0x100, DLOC+0x100, /* 64-65 */
@ -128,7 +93,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* 68-69 */
ACCUM+0x000, IMPLY+0x000, /* 6a-6b */
ABSIND+0x200, ABS+0x200, /* 6c-6d */
ABS+0x200, LONG+0x300, /* 6e-6f */
ABS+0x200, ABSLONG+0x300, /* 6e-6f */
DISP8+0x100, DLOCINDY+0x100, /* 70-71 */
DLOCIND+0x100, DISP8SINDY+0x100, /* 72-73 */
DLOCX+0x100, DLOCX+0x100, /* 74-75 */
@ -136,7 +101,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, ABSY+0x200, /* 78-79 */
IMPLY+0x000, IMPLY+0x000, /* 7a-7b */
ABSXIND+0x200, ABSX+0x200, /* 7c-7d */
ABSX+0x200, LONGX+0x300, /* 7e-7f */
ABSX+0x200, ABSLONGX+0x300, /* 7e-7f */
DISP8+0x100, DLOCXIND+0x100, /* 80-81 */
DISP16+0x200, DISP8S+0x100, /* 82-83 */
DLOC+0x100, DLOC+0x100, /* 84-85 */
@ -144,7 +109,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* 88-89 */
IMPLY+0x000, IMPLY+0x000, /* 8a-8b */
ABS+0x200, ABS+0x200, /* 8c-8d */
ABS+0x200, LONG+0x300, /* 8e-8f */
ABS+0x200, ABSLONG+0x300, /* 8e-8f */
DISP8+0x100, DLOCINDY+0x100, /* 90-91 */
DLOCIND+0x100, DISP8SINDY+0x100, /* 92-93 */
DLOCX+0x100, DLOCX+0x100, /* 94-95 */
@ -152,7 +117,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, ABSY+0x200, /* 98-99 */
IMPLY+0x000, IMPLY+0x000, /* 9a-9b */
ABS+0x200, ABSX+0x200, /* 9c-9d */
ABSX+0x200, LONGX+0x300, /* 9e-9f */
ABSX+0x200, ABSLONGX+0x300, /* 9e-9f */
IMMED+0x500, DLOCXIND+0x100, /* a0-a1 */
IMMED+0x500, DISP8S+0x100, /* a2-a3 */
DLOC+0x100, DLOC+0x100, /* a4-a5 */
@ -160,7 +125,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* a8-a9 */
IMPLY+0x000, IMPLY+0x000, /* aa-ab */
ABS+0x200, ABS+0x200, /* ac-ad */
ABS+0x200, LONG+0x300, /* ae-af */
ABS+0x200, ABSLONG+0x300, /* ae-af */
DISP8+0x100, DLOCINDY+0x100, /* b0-b1 */
DLOCIND+0x100, DISP8SINDY+0x100, /* b2-b3 */
DLOCX+0x100, DLOCX+0x100, /* b4-b5 */
@ -168,7 +133,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, ABSY+0x200, /* b8-b9 */
IMPLY+0x000, IMPLY+0x000, /* ba-bb */
ABSX+0x200, ABSX+0x200, /* bc-bd */
ABSY+0x200, LONGX+0x300, /* be-bf */
ABSY+0x200, ABSLONGX+0x300, /* be-bf */
IMMED+0x500, DLOCXIND+0x100, /* c0-c1 */
REPVAL+0x100, DISP8S+0x100, /* c2-c3 */
DLOC+0x100, DLOC+0x100, /* c4-c5 */
@ -176,7 +141,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* c8-c9 */
IMPLY+0x000, IMPLY+0x000, /* ca-cb */
ABS+0x200, ABS+0x200, /* cc-cd */
ABS+0x200, LONG+0x300, /* ce-cf */
ABS+0x200, ABSLONG+0x300, /* ce-cf */
DISP8+0x100, DLOCINDY+0x100, /* d0-d1 */
DLOCIND+0x100, DISP8SINDY+0x100, /* d2-d3 */
DLOC+0x100, DLOCX+0x100, /* d4-d5 */
@ -184,7 +149,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, ABSY+0x200, /* d8-d9 */
IMPLY+0x000, IMPLY+0x000, /* da-db */
ABSIND+0x200, ABSX+0x200, /* dc-dd */
ABSX+0x200, LONGX+0x300, /* de-df */
ABSX+0x200, ABSLONGX+0x300, /* de-df */
IMMED+0x500, DLOCXIND+0x100, /* e0-e1 */
SEPVAL+0x100, DISP8S+0x100, /* e2-e3 */
DLOC+0x100, DLOC+0x100, /* e4-e5 */
@ -192,7 +157,7 @@ const word32 disas_types[256] = {
IMPLY+0x000, IMMED+0x400, /* e8-e9 */
IMPLY+0x000, IMPLY+0x000, /* ea-eb */
ABS+0x200, ABS+0x200, /* ec-ed */
ABS+0x200, LONG+0x300, /* ee-ef */
ABS+0x200, ABSLONG+0x300, /* ee-ef */
DISP8+0x100, DLOCINDY+0x100, /* f0-f1 */
DLOCIND+0x100, DISP8SINDY+0x100, /* f2-f3 */
IMMED+0x200, DLOCX+0x100, /* f4-f5 */
@ -200,5 +165,5 @@ const word32 disas_types[256] = {
IMPLY+0x000, ABSY+0x200, /* f8-f9 */
IMPLY+0x000, IMPLY+0x000, /* fa-fb */
ABSXIND+0x200, ABSX+0x200, /* fc-fd */
ABSX+0x200, LONGX+0x300, /* fe-ff */
ABSX+0x200, ABSLONGX+0x300, /* fe-ff */
};

41
src/disasm.h Normal file
View File

@ -0,0 +1,41 @@
/*
GSPLUS - Advanced Apple IIGS Emulator Environment
Based on the KEGS emulator written by Kent Dickey
See COPYRIGHT.txt for Copyright information
See LICENSE.txt for license (GPL v2)
*/
enum {
ABS = 1,
ABSX,
ABSY,
ABSIND,
ABSXIND,
IMPLY,
ACCUM,
IMMED,
JUST8,
DLOC,
DLOCX,
DLOCY,
ABSLONG,
ABSLONGX,
DLOCIND,
DLOCINDY,
DLOCXIND,
DLOCBRAK,
DLOCBRAKY,
DISP8,
DISP8S,
DISP8SINDY,
DISP16,
MVPMVN,
REPVAL,
SEPVAL
};
extern const char * const disasm_opcodes[256];
extern const unsigned disasm_types[256];

View File

@ -24,7 +24,6 @@
# define FCYCS_PTR_FCYCLES_ROUND_SLOW
#endif
extern int g_dbg_step;
extern int halt_sim;
extern int g_code_red;
extern int g_ignore_halts;
@ -53,9 +52,6 @@ extern byte *g_rom_fc_ff_ptr_allocated;
extern byte *g_rom_cards_ptr_allocated;
extern byte *g_dummy_memory1_ptr_allocated;
extern int g_num_breakpoints;
extern word32 g_breakpts[];
extern Pc_log *g_log_pc_ptr;
extern Pc_log *g_log_pc_start_ptr;
extern Pc_log *g_log_pc_end_ptr;
@ -156,7 +152,7 @@ extern word32 slow_mem_changed[];
stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \
wstat = PTR2WORD(stat) & 0xff; \
ptr = stat - wstat + ((addr) & 0xff); \
if(wstat & (1 << (31 - BANK_IO_BIT)) || iostrobe == 1) { \
if(wstat & BANK_IO_TMP || iostrobe == 1) { \
fcycles_tmp1 = fcycles; \
dest = get_memory8_io_stub((addr), stat, \
&fcycles_tmp1, fplus_x_m1); \
@ -172,7 +168,7 @@ extern word32 slow_mem_changed[];
stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \
wstat = PTR2WORD(stat) & 0xff; \
ptr = stat - wstat + ((addr) & 0xff); \
if((wstat & (1 << (31 - BANK_IO_BIT))) || (((addr) & 0xff) == 0xff)) { \
if((wstat & BANK_IO_TMP) || (((addr) & 0xff) == 0xff)) { \
fcycles_tmp1 = fcycles; \
dest = get_memory16_pieces_stub((addr), stat, \
&fcycles_tmp1, fplus_ptr, in_bank); \
@ -188,7 +184,7 @@ extern word32 slow_mem_changed[];
stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \
wstat = PTR2WORD(stat) & 0xff; \
ptr = stat - wstat + ((addr) & 0xff); \
if((wstat & (1 << (31 - BANK_IO_BIT))) || (((addr) & 0xfe) == 0xfe)) { \
if((wstat & BANK_IO_TMP) || (((addr) & 0xfe) == 0xfe)) { \
fcycles_tmp1 = fcycles; \
dest = get_memory24_pieces_stub((addr), stat, \
&fcycles_tmp1, fplus_ptr, in_bank); \
@ -218,43 +214,77 @@ extern word32 slow_mem_changed[];
GET_MEMORY16(save_addr, dest, 1); \
}
/*
_ macros do not do any MMU checking
*/
#define PUSH8(arg) \
SET_MEMORY8(stack, arg); \
#if 1
#define MMU_CHECK(addr, val, bytes, in_page, in_bank) \
if (abort_support && check_mp_breakpoints(addr, val, bytes, in_page, in_bank)) { \
g_ret1 = RET_MP; \
g_ret2 = saved_pc; \
kpc = saved_pc; \
psr = saved_psr; \
goto finish; \
}
#else
#define MMU_CHECK(addr, val, bytes, in_page, in_bank)
#endif
#define PUSH8(arg) \
MMU_CHECK(stack, arg, 1, 0, 0) \
_PUSH8(arg) \
#define _PUSH8(arg) \
_SET_MEMORY8(stack, arg); \
stack--; \
if(psr & 0x100) { \
stack = 0x100 | (stack & 0xff); \
stack = 0x100 | (stack & 0xff); \
} \
stack = stack & 0xffff;
#define PUSH16(arg) \
#define PUSH16(arg) \
tmp2 = stack - 1; \
if (psr >> 8) tmp2 = (tmp2 & 0xff) | 0x0100; \
tmp2 &= 0xffff; \
MMU_CHECK(tmp2, arg, 2, psr >> 8, 1) \
_PUSH16(arg)
#define _PUSH16(arg) \
if((stack & 0xfe) == 0) { \
/* stack will cross page! */ \
PUSH8((arg) >> 8); \
PUSH8(arg); \
_PUSH8((arg) >> 8); \
_PUSH8(arg); \
} else { \
stack -= 2; \
stack = stack & 0xffff; \
SET_MEMORY16(stack + 1, arg, 1); \
_SET_MEMORY16(stack + 1, arg, 1); \
}
#define PUSH16_UNSAFE(arg) \
#define PUSH16_UNSAFE(arg) \
MMU_CHECK((stack - 1) & 0xffff, arg, 2, 0, 1) \
_PUSH16_UNSAFE(arg)
#define _PUSH16_UNSAFE(arg) \
save_addr = (stack - 1) & 0xffff; \
stack -= 2; \
if(psr & 0x100) { \
stack = 0x100 | (stack & 0xff); \
stack = 0x100 | (stack & 0xff); \
} \
stack = stack & 0xffff; \
SET_MEMORY16(save_addr, arg, 1);
_SET_MEMORY16(save_addr, arg, 1);
#define PUSH24_UNSAFE(arg) \
#define PUSH24_UNSAFE(arg) \
MMU_CHECK((stack - 2) & 0xffff, arg, 3, 0, 1) \
_PUSH24_UNSAFE(arg)
#define _PUSH24_UNSAFE(arg) \
save_addr = (stack - 2) & 0xffff; \
stack -= 3; \
if(psr & 0x100) { \
stack = 0x100 | (stack & 0xff); \
stack = 0x100 | (stack & 0xff); \
} \
stack = stack & 0xffff; \
SET_MEMORY24(save_addr, arg, 1);
_SET_MEMORY24(save_addr, arg, 1);
#define PULL8(dest) \
stack++; \
@ -303,7 +333,11 @@ extern word32 slow_mem_changed[];
} \
}
#define SET_MEMORY8(addr, val) \
#define SET_MEMORY8(addr, val) \
MMU_CHECK(addr, val, 1, 0, 0) \
_SET_MEMORY8(addr, val)
#define _SET_MEMORY8(addr, val) \
LOG_DATA_MACRO(addr, val, 8); \
CYCLES_PLUS_1; \
stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \
@ -318,8 +352,12 @@ extern word32 slow_mem_changed[];
*ptr = val; \
}
#define SET_MEMORY16(addr, val, in_bank) \
MMU_CHECK(addr, val, 2, 0, in_bank) \
_SET_MEMORY16(addr, val, in_bank)
#define SET_MEMORY16(addr, val, in_bank) \
#define _SET_MEMORY16(addr, val, in_bank) \
LOG_DATA_MACRO(addr, val, 16); \
stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \
wstat = PTR2WORD(stat) & 0xff; \
@ -335,7 +373,12 @@ extern word32 slow_mem_changed[];
ptr[1] = (val) >> 8; \
}
#define SET_MEMORY24(addr, val, in_bank) \
#define SET_MEMORY24(addr, val, in_bank) \
MMU_CHECK(addr, val, 3, 0, in_bank) \
_SET_MEMORY24(addr, val, in_bank)
#define _SET_MEMORY24(addr, val, in_bank) \
LOG_DATA_MACRO(addr, val, 24); \
stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \
wstat = PTR2WORD(stat) & 0xff; \
@ -352,19 +395,99 @@ extern word32 slow_mem_changed[];
ptr[2] = (val) >> 16; \
}
void check_breakpoints(word32 addr) {
int count;
extern int g_num_bp_breakpoints;
extern word32 g_bp_breakpoints[];
extern int g_num_tp_breakpoints;
extern word32 g_tp_breakpoints[];
extern int g_num_mp_breakpoints;
extern word32 g_mp_breakpoints[];
extern word32 g_abort_address;
extern word32 g_abort_value;
extern word32 g_abort_bytes;
int check_bp_breakpoints(word32 addr) {
int i;
count = g_num_breakpoints;
for(i = 0; i < count; i++) {
if((g_breakpts[i] & 0xffffff) == addr) {
g_dbg_step = -2;
halt2_printf("Hit breakpoint at %06x\n", addr);
for (i = 0; i < g_num_bp_breakpoints; ++i) {
if (g_bp_breakpoints[i] == addr) {
return 1;
}
}
/* temp breakpoints */
for (i = 0; i < g_num_tp_breakpoints; ++i) {
if (g_tp_breakpoints[i] == addr) {
return 1;
}
}
return 0;
}
/* 65816 abort just pushes the orignal pc (-1?) on the stack.
MMU hardware could, of course, store the address [and value?]
*/
int check_mp_breakpoints(word32 addr, word32 value, unsigned bytes, int in_page, int in_bank) {
byte *stat1;
byte *stat2;
word32 wstat;
word32 mask = 0xffffff;
int i;
/* assumptions:
* bytes is 1-3, so no possibility of crossing multiple pages
* g_mp_breakpoints is in ascending order.
*/
word32 a1 = addr;
word32 a2 = addr + bytes - 1;
if (in_page) {
mask = 0x00ff;
} else if (in_bank) {
mask = 0xffff;
} else {
mask = 0xffffff;
}
a2 = (a2 & mask) | (addr & ~mask);
stat1 = GET_PAGE_INFO_WR(((a1) >> 8) & 0xffff);
stat2 = GET_PAGE_INFO_WR(((a2) >> 8) & 0xffff);
wstat = PTR2WORD(stat1) | PTR2WORD(stat2);
if (wstat & BANK_BREAK) {
for (i = 0; i < g_num_mp_breakpoints; ++i) {
word32 bp = g_mp_breakpoints[i];
if (bp >= a1 && bp <= a2) {
abort_it:
g_abort_address = addr;
g_abort_bytes = bytes;
mask = (1 << (bytes << 3))-1;
g_abort_value = value & mask;
return 1;
}
if (a2 < a1) {
/* special logic for page/bank-wrapping... */
if (bp >= a1 && bp <= (a1 | mask)) goto abort_it;
if (bp >= (a1 & ~mask) && bp <= a2) goto abort_it;
}
}
}
return 0;
}
word32 get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr,
double fplus_x_m1) {
double fcycles;
@ -372,9 +495,6 @@ word32 get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr,
byte *ptr;
wstat = PTR2WORD(stat) & 0xff;
if(wstat & BANK_BREAK) {
check_breakpoints(addr);
}
fcycles = *fcycs_ptr;
if(wstat & BANK_IO2_TMP || iostrobe == 1) {
FCYCLES_ROUND;
@ -449,16 +569,14 @@ void set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr,
word32 wstat;
wstat = PTR2WORD(stat) & 0xff;
if(wstat & (1 << (31 - BANK_BREAK_BIT))) {
check_breakpoints(addr);
}
ptr = stat - wstat + ((addr) & 0xff); \
ptr = stat - wstat + ((addr) & 0xff);
fcycles = *fcycs_ptr;
if(wstat & (1 << (31 - BANK_IO2_BIT))) {
if(wstat & BANK_IO2_TMP) {
FCYCLES_ROUND;
*fcycs_ptr = fcycles;
set_memory_io((addr), val, fcycs_ptr);
} else if(wstat & (1 << (31 - BANK_SHADOW_BIT))) {
} else if(wstat & BANK_SHADOW) {
FCYCS_PTR_FCYCLES_ROUND_SLOW;
tmp1 = (addr & 0xffff);
setmem_tmp1 = g_slow_memory_ptr[tmp1];
@ -468,7 +586,7 @@ void set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr,
slow_mem_changed[tmp1 >> CHANGE_SHIFT] |=
(1 << (31-((tmp1 >> SHIFT_PER_CHANGE) & 0x1f)));
}
} else if(wstat & (1 << (31 - BANK_SHADOW2_BIT))) {
} else if(wstat & BANK_SHADOW2) {
FCYCS_PTR_FCYCLES_ROUND_SLOW;
tmp2 = (addr & 0xffff);
tmp1 = 0x10000 + tmp2;
@ -493,12 +611,12 @@ void set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
word32 addrp1;
word32 wstat;
fcycles = *fcycs_ptr;
SET_MEMORY8(addr, val);
_SET_MEMORY8(addr, val);
addrp1 = addr + 1;
if(in_bank) {
addrp1 = (addr & 0xff0000) + (addrp1 & 0xffff);
}
SET_MEMORY8(addrp1, val >> 8);
_SET_MEMORY8(addrp1, val >> 8);
*fcycs_ptr = fcycles;
}
@ -516,17 +634,17 @@ void set_memory24_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
fcycles = *fcycs_ptr;
fplus_1 = fplus_ptr->plus_1;
fplus_x_m1 = fplus_ptr->plus_x_minus_1;
SET_MEMORY8(addr, val);
_SET_MEMORY8(addr, val);
addrp1 = addr + 1;
if(in_bank) {
addrp1 = (addr & 0xff0000) + (addrp1 & 0xffff);
}
SET_MEMORY8(addrp1, val >> 8);
_SET_MEMORY8(addrp1, val >> 8);
addrp2 = addr + 2;
if(in_bank) {
addrp2 = (addr & 0xff0000) + (addrp2 & 0xffff);
}
SET_MEMORY8(addrp2, val >> 16);
_SET_MEMORY8(addrp2, val >> 16);
*fcycs_ptr = fcycles;
}
@ -591,7 +709,7 @@ void set_memory_c(word32 addr, word32 val, int cycs) {
fcycles = g_cur_dcycs - g_last_vbl_dcycs;
fplus_1 = 0;
fplus_x_m1 = 0;
SET_MEMORY8(addr, val);
_SET_MEMORY8(addr, val);
}
void set_memory16_c(word32 addr, word32 val, int cycs) {
@ -606,7 +724,7 @@ void set_memory16_c(word32 addr, word32 val, int cycs) {
fplus_1 = 0;
fplus_2 = 0;
fplus_x_m1 = 0;
SET_MEMORY16(addr, val, 0);
_SET_MEMORY16(addr, val, 0);
}
void set_memory24_c(word32 addr, word32 val, int cycs) {
@ -760,42 +878,37 @@ void fixed_memory_ptrs_shut() {
g_rom_cards_ptr = NULL;
}
#if defined(_MSC_VER)
#include <intrin.h>
#elif defined(__GNUC__)
#if defined(__i386__) || defined(__x86_64__)
#include <x86intrin.h>
#elif defined(__powerpc__) || defined(__ppc__)
#define __rdtsc() __builtin_ppc_mftb()
#else
#warning __rdtsc unavailable.
#define __rdtsc() 0
#endif
#else
#warning __rdtsc unavailable.
#define __rdtsc() 0
#endif
word32 get_itimer() {
#if defined(_WIN32)
LARGE_INTEGER count;
if (QueryPerformanceCounter(&count))
return count.LowPart;
else
return 0;
#elif defined(__i386) && defined(__GNUC__)
/* Here's my bad ia32 asm code to do rdtsc */
/* Linux source uses: */
/* asm volatile("rdtsc" : "=a"(ret) : : "edx"); */
/* asm volatile("rdtsc" : "=%eax"(ret) : : "%edx"); */
/* GCC bug report 2001-03/msg00786.html used: */
/*register word64 dtmp; */
/*asm volatile ("rdtsc" : "=A" (dtmp)); */
/*return (word32)dtmp; */
register word32 ret;
asm volatile ("rdtsc;movl %%eax,%0" : "=r" (ret) : : "%eax","%edx");
return ret;
#elif defined(__POWERPC__) && defined(__GNUC__)
register word32 ret;
asm volatile ("mftb %0" : "=r" (ret));
return ret;
#else
return 0;
#endif
return __rdtsc();
}
void set_halt_act(int val) {
if(val == 1 && g_ignore_halts && !g_user_halt_bad) {
extern int g_dbg_shell;
if(val == 1 && g_ignore_halts && !g_user_halt_bad && !g_dbg_shell) {
g_code_red++;
} else {
halt_sim |= val;
@ -865,18 +978,23 @@ word32 get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fpl
return arg;
}
#define FETCH_OPCODE \
addr = kpc; \
#define FETCH_OPCODE \
addr = saved_pc = kpc; \
saved_psr = psr; \
CYCLES_PLUS_2; \
stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \
wstat = PTR2WORD(stat) & 0xff; \
ptr = stat - wstat + ((addr) & 0xff); \
arg_ptr = ptr; \
opcode = *ptr; \
if((wstat & (1 << (31-BANK_IO_BIT))) || ((addr & 0xff) > 0xfc)) { \
if(wstat & BANK_BREAK) { \
check_breakpoints(addr); \
} \
if (wstat & BANK_BREAK) { \
wstat &= ~BANK_BREAK; \
if (kpc_support && check_bp_breakpoints(addr)) { \
FINISH(RET_BP, addr); \
} \
} \
if((wstat & BANK_IO_TMP) || ((addr & 0xff) > 0xfc)) { \
if((addr & 0xfffff0) == 0x00c700) { \
if(addr == 0xc700) { \
FINISH(RET_C700, 0); \
@ -886,7 +1004,7 @@ word32 get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fpl
FINISH(RET_C70D, 0); \
} \
} \
if(wstat & (1 << (31 - BANK_IO2_BIT)) || iostrobe == 1) { \
if(wstat & BANK_IO2_TMP || iostrobe == 1) { \
FCYCLES_ROUND; \
fcycles_tmp1 = fcycles; \
opcode = get_memory_io((addr), &fcycles_tmp1); \
@ -935,6 +1053,17 @@ int enter_engine(Engine_reg *engine_ptr) {
word32 addr_latch;
word32 tmp1, tmp2;
word32 flags = 0;
word32 saved_pc = 0;
word32 saved_psr = 0;
word32 abort_support = g_num_mp_breakpoints ? 1 : 0;
word32 kpc_support = g_num_bp_breakpoints + g_num_tp_breakpoints ? 1 : 0;
flags = engine_ptr->flags;
if (flags & FLAG_IGNORE_MP) abort_support = 0;
if (flags & FLAG_IGNORE_BP) kpc_support = 0;
tmp_pc_ptr = 0;

View File

@ -1,36 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2012 for Windows Desktop
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsport", "gsport.vcxproj", "{0B4E527A-DB50-4B5F-9B08-303ABAF7356A}"
ProjectSection(ProjectDependencies) = postProject
{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B} = {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}
{E810477A-E004-4308-A58A-21393213EF89} = {E810477A-E004-4308-A58A-21393213EF89}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tfe", "tfe\tfe.vcxproj", "{E810477A-E004-4308-A58A-21393213EF89}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "atbridge", "atbridge\atbridge.vcxproj", "{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Debug|Win32.ActiveCfg = Debug|Win32
{0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Debug|Win32.Build.0 = Debug|Win32
{0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Release|Win32.ActiveCfg = Release|Win32
{0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Release|Win32.Build.0 = Release|Win32
{E810477A-E004-4308-A58A-21393213EF89}.Debug|Win32.ActiveCfg = Debug|Win32
{E810477A-E004-4308-A58A-21393213EF89}.Debug|Win32.Build.0 = Debug|Win32
{E810477A-E004-4308-A58A-21393213EF89}.Release|Win32.ActiveCfg = Release|Win32
{E810477A-E004-4308-A58A-21393213EF89}.Release|Win32.Build.0 = Release|Win32
{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Debug|Win32.ActiveCfg = Debug|Win32
{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Debug|Win32.Build.0 = Debug|Win32
{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Release|Win32.ActiveCfg = Release|Win32
{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,203 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0B4E527A-DB50-4B5F-9B08-303ABAF7356A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>gsport</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN_SOUND;GSPLUS_LITTLE_ENDIAN;HAVE_TFE;HAVE_ATBRIDGE;TOGGLE_STATUS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<ErrorReporting>Prompt</ErrorReporting>
<FunctionLevelLinking>true</FunctionLevelLinking>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>IPHLPAPI.lib;Winmm.lib;Ws2_32.lib;Shlwapi.lib;$(SolutionDir)$(Configuration)\tfe.lib;;$(SolutionDir)$(Configuration)\atbridge.lib;%(AdditionalDependencies)</AdditionalDependencies>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN_SOUND;GSPLUS_LITTLE_ENDIAN;HAVE_ATBRIDGE;HAVE_TFE;TOGGLE_STATUS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<BufferSecurityCheck>false</BufferSecurityCheck>
<CompileAs>CompileAsC</CompileAs>
<ErrorReporting>Prompt</ErrorReporting>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<OmitFramePointers>true</OmitFramePointers>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>IPHLPAPI.lib;Winmm.lib;Ws2_32.lib;Shlwapi.lib;$(SolutionDir)$(Configuration)\tfe.lib;;$(SolutionDir)$(Configuration)\atbridge.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="16inst_c.h" />
<ClInclude Include="8inst_c.h" />
<ClInclude Include="adb.h" />
<ClInclude Include="config.h" />
<ClInclude Include="defc.h" />
<ClInclude Include="defcomm.h" />
<ClInclude Include="defs.h" />
<ClInclude Include="defs_instr.h" />
<ClInclude Include="disas.h" />
<ClInclude Include="gsportfont.h" />
<CustomBuild Include="instable.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">perl make_inst c 8 instable.h &gt; 8inst_c.h
perl make_inst c 16 instable.h &gt; 16inst_c.h
perl make_inst s 8 instable.h &gt; 8inst_s.h
perl make_inst s 16 instable.h &gt; 16inst_s.h</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h</Outputs>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">perl make_inst c 8 instable.h &gt; 8inst_c.h
perl make_inst c 16 instable.h &gt; 16inst_c.h
perl make_inst s 8 instable.h &gt; 8inst_s.h
perl make_inst s 16 instable.h &gt; 16inst_s.h</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h</Outputs>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects>
</CustomBuild>
<ClInclude Include="scc_llap.h" />
<ClInclude Include="win_keymap.h" />
<ClInclude Include="iwm.h" />
<ClInclude Include="iwm_35_525.h" />
<ClInclude Include="op_routs.h" />
<ClInclude Include="printer.h" />
<ClInclude Include="printer_charmaps.h" />
<ClInclude Include="imagewriter.h" />
<ClInclude Include="iw_charmaps.h" />
<ClInclude Include="prodos.h" />
<ClInclude Include="prodos_protos.h" />
<ClInclude Include="protos.h" />
<ClInclude Include="protos_engine_c.h" />
<ClInclude Include="protos_macdriver.h" />
<ClInclude Include="protos_macsnd_driver.h" />
<ClInclude Include="protos_windriver.h" />
<ClInclude Include="protos_xdriver.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="scc.h" />
<ClInclude Include="size_c.h" />
<CustomBuild Include="size_tab.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">perl make_size c size_tab.h &gt; size_c.h
perl make_size s size_tab.h &gt; size_s.h
perl make_size 8 size_tab.h &gt; 8size_s.h
perl make_size 16 size_tab.h &gt; 16size_s.h
perl make_size c size_tab.h &gt; size_c.h</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">size_c.h size_s.h 8size_s.h 16size_s.h</Outputs>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">perl make_size c size_tab.h &gt; size_c.h
perl make_size s size_tab.h &gt; size_s.h
perl make_size 8 size_tab.h &gt; 8size_s.h
perl make_size 16 size_tab.h &gt; 16size_s.h
perl make_size c size_tab.h &gt; size_c.h</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">size_c.h size_s.h 8size_s.h 16size_s.h</Outputs>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects>
</CustomBuild>
<ClInclude Include="sound.h" />
<ClInclude Include="superhires.h" />
<ClInclude Include="support.h" />
<ClInclude Include="tfe\protos_tfe.h" />
<ClInclude Include="winresource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="adb.c" />
<ClCompile Include="clock.c" />
<ClCompile Include="compile_time.c" />
<ClCompile Include="config.c" />
<ClCompile Include="dis.c" />
<ClCompile Include="engine_c.c" />
<ClCompile Include="iwm.c" />
<ClCompile Include="joystick_driver.c" />
<ClCompile Include="moremem.c" />
<ClCompile Include="paddles.c" />
<ClCompile Include="parallel.c" />
<ClCompile Include="printer.cpp">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="scc_imagewriter.c" />
<ClCompile Include="imagewriter.cpp">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="scc.c" />
<ClCompile Include="scc_llap.c" />
<ClCompile Include="scc_socket_driver.c" />
<ClCompile Include="scc_windriver.c" />
<ClCompile Include="sim65816.c" />
<ClCompile Include="smartport.c" />
<ClCompile Include="sound.c" />
<ClCompile Include="sound_driver.c" />
<ClCompile Include="video.c" />
<ClCompile Include="win32snd_driver.c" />
<ClCompile Include="win_console.c" />
<ClCompile Include="win_generic.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="win32.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,217 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="16inst_c.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="8inst_c.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="adb.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="defc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="defcomm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="defs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="defs_instr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="disas.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gsportfont.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="iwm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="iwm_35_525.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="op_routs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="printer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="printer_charmaps.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="imagewriter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="iw_charmaps.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="prodos.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="prodos_protos.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="protos.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="protos_engine_c.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="protos_macdriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="protos_macsnd_driver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="protos_windriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="protos_xdriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="scc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="size_c.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sound.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="superhires.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="support.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="winresource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="tfe\protos_tfe.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="win_keymap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="scc_llap.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="adb.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="clock.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="compile_time.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="config.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dis.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="engine_c.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="iwm.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="joystick_driver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="moremem.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="paddles.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scc_socket_driver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scc_windriver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sim65816.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="smartport.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sound.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sound_driver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="video.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="win32snd_driver.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="win_console.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="win_generic.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="parallel.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="printer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scc_imagewriter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imagewriter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scc_llap.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="size_tab.h">
<Filter>Header Files</Filter>
</CustomBuild>
<CustomBuild Include="instable.h">
<Filter>Header Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="win32.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -8,9 +8,129 @@
#include "defc.h"
#include "glog.h"
#include <signal.h>
extern int get_byte_at_address(int addr);
static unsigned char fix_char(unsigned char c) {
// inverse upper case
if (c >= 0x00 && c <= 0x1f) return c + 0x40;
// inverse special
if (c >= 0x20 && c <= 0x3f) return c;
// mouse text
if (c >= 0x40 && c <= 0x5f) return ' ';
// inverse lowercase
if (c >= 0x60 && c <= 0x7f) return c;
// uppercase normal
if (c >= 0x80 && c <= 0x9f) return c - 0x40;
// special characters, uppercase normal, lowercase normal.
if (c >= 0xa0 && c <= 0xff) return c - 0x80;
return ' ';
}
static void siginfo_handler(int signum) {
static unsigned table[] = {
0x0400,
0x0480,
0x0500,
0x0580,
0x0600,
0x0680,
0x0700,
0x0780,
0x0428,
0x04A8,
0x0528,
0x05A8,
0x0628,
0x06A8,
0x0728,
0x07A8,
0x0450,
0x04D0,
0x0550,
0x05D0,
0x0650,
0x06D0,
0x0750,
0x07D0,
};
extern int g_cur_a2_stat;
extern int get_byte_at_address(int addr);
if (g_cur_a2_stat & ALL_STAT_SUPER_HIRES) return; // not text...
int st80 = g_cur_a2_stat & ALL_STAT_VID80 /* ALL_STAT_ST80 */;
//if (!(g_cur_a2_stat & ALL_STAT_TEXT)) return; // text is not enabled.
char buffer[80+1];
for (int row = 0; row < 24; ++row) {
unsigned address = table[row];
int column = 0;
memset(buffer, ' ', sizeof(buffer));
for(int j = 0; j < 40; ++j, ++address) {
unsigned char c;
if (st80) {
c = get_byte_at_address(0xe10000 + address);
c = fix_char(c);
buffer[column++] = c;
}
c = get_byte_at_address(0xe00000 + address);
c = fix_char(c);
buffer[column++] = c;
}
if (st80) {
buffer[80] = '\n';
write(1, buffer, 81);
} else {
buffer[40] = '\n';
write(1, buffer, 41);
}
}
write(1, "\n\n", 2);
}
int
main(int argc, char **argv)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_RESTART;
sa.sa_handler = siginfo_handler;
#if defined(SIGINFO)
/* control-T by default */
sigaction(SIGINFO, &sa, NULL);
//signal(SIGINFO, siginfo_handler);
#endif
//signal(SIGUSR1, siginfo_handler);
sigaction(SIGUSR1, &sa, NULL);
return gsplusmain(argc, argv);
}

View File

@ -1,14 +1,9 @@
#define _BSD_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <libgen.h>
#include "defc.h"
#include "gsos.h"
@ -18,6 +13,12 @@
#include <Windows.h>
#endif
#ifdef _MSC_VER
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
#include "host_common.h"
@ -149,59 +150,6 @@ void host_text_to_merlin(byte *buffer, size_t size) {
}
/*
* error remapping.
* NOTE - GS/OS errors are a superset of P8 errors
*/
static word32 enoent(const char *path) {
/*
some op on path return ENOENT. check if it's
fileNotFound or pathNotFound
*/
char *p = (char *)path;
for(;;) {
struct stat st;
p = dirname(p);
if (p == NULL) break;
if (p[0] == '.' && p[1] == 0) break;
if (p[0] == '/' && p[1] == 0) break;
if (stat(p, &st) < 0) return pathNotFound;
}
return fileNotFound;
}
word32 host_map_errno(int xerrno) {
switch(xerrno) {
case 0: return 0;
case EBADF:
return invalidAccess;
#ifdef EDQUOT
case EDQUOT:
#endif
case EFBIG:
return volumeFull;
case ENOENT:
return fileNotFound;
case ENOTDIR:
return pathNotFound;
case ENOMEM:
return outOfMem;
case EEXIST:
return dupPathname;
case ENOTEMPTY:
return invalidAccess;
default:
return drvrIOError;
}
}
word32 host_map_errno_path(int xerrno, const char *path) {
if (xerrno == ENOENT) return enoent(path);
return host_map_errno(xerrno);
}
const char *host_error_name(word16 error) {
static char *errors[] = {
"",

View File

@ -26,6 +26,11 @@
#include "host_common.h"
#ifdef _MSC_VER
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
#define LEVEL 0xBFD8 // current file level
#define DEVNUM 0xBF30 // last slot / drive

View File

@ -71,27 +71,43 @@ brk_testing_SYM
DEC_KPC2;
CYCLES_PLUS_2
b dispatch_done
depi RET_BREAK,3,4,ret0
depi RET_BRK,3,4,ret0
#else
GET_1BYTE_ARG;
if(g_testing) {
CYCLES_PLUS_2;
FINISH(RET_BREAK, arg);
if (flags & FLAG_WANT_BRK) {
if (~flags & FLAG_IGNORE_BRK) {
CYCLES_PLUS_2;
FINISH(RET_BRK, arg);
}
}
g_num_brk++;
INC_KPC_2;
g_num_brk++;
psr = psr & (~0x82);
psr |= (neg << 7);
psr |= ((!zero) << 1);
tmp1 = psr & 0xff;
if(psr & 0x100) {
PUSH16(kpc & 0xffff);
PUSH8(psr & 0xff);
MMU_CHECK(
((stack - 2) & 0xff) | 0x0100,
(kpc << 8) | tmp1, 3, 1, 1
)
_PUSH16(kpc & 0xffff);
_PUSH8(tmp1);
GET_MEMORY16(0xfffe, kpc, 0);
dbank = 0;
} else {
PUSH8(kpc >> 16);
PUSH16(kpc);
PUSH8(psr & 0xff);
MMU_CHECK(
(stack - 3) & 0xffff,
(kpc << 8) | tmp1, 4, 0, 1
)
_PUSH8(kpc >> 16);
_PUSH16(kpc);
_PUSH8(tmp1);
GET_MEMORY16(0xffe6, kpc, 0);
halt_printf("Halting for native break!\n");
//halt_printf("Halting for native break!\n");
}
kpc = kpc & 0xffff;
psr |= 0x4;
@ -153,18 +169,42 @@ cop_native_SYM
#else
g_num_cop++;
GET_1BYTE_ARG;
if (flags & FLAG_WANT_COP) {
if (~flags & FLAG_IGNORE_BRK) {
CYCLES_PLUS_2;
FINISH(RET_COP, arg);
}
}
INC_KPC_2;
g_num_cop++;
psr = psr & (~0x82);
psr |= (neg << 7);
psr |= ((!zero) << 1);
tmp1 = psr & 0xff;
if(psr & 0x100) {
halt_printf("Halting for emul COP at %04x\n", kpc);
PUSH16(kpc & 0xffff);
PUSH8(psr & 0xff);
//halt_printf("Halting for emul COP at %04x\n", kpc);
MMU_CHECK(
((stack - 2) & 0xff) | 0x0100,
(kpc << 8) | tmp1, 3, 1, 1
)
_PUSH16(kpc & 0xffff);
_PUSH8(tmp1);
GET_MEMORY16(0xfff4, kpc, 0);
dbank = 0;
} else {
PUSH8(kpc >> 16);
PUSH16(kpc & 0xffff);
PUSH8(psr & 0xff);
MMU_CHECK(
(stack - 3) & 0xffff,
(kpc << 8) | tmp1, 4, 0, 1
)
_PUSH8(kpc >> 16);
_PUSH16(kpc & 0xffff);
_PUSH8(tmp1);
GET_MEMORY16(0xffe4, kpc, 0);
}
kpc = kpc & 0xffff;

View File

@ -6,9 +6,10 @@
*/
#include "defc.h"
#include <stddef.h>
#ifdef HAVE_TFE
#include "tfe/protos_tfe.h"
#ifdef HAVE_RAWNET
#include "rawnet/cs8900.h"
#endif
extern char const g_gsplus_version_str[];
@ -24,8 +25,16 @@ extern unsigned char iostrobe;
extern word32 slow_mem_changed[];
extern int g_num_breakpoints;
extern word32 g_breakpts[];
extern int g_num_mp_breakpoints;
extern word32 g_mp_breakpoints[];
extern int g_num_bp_breakpoints;
extern word32 g_bp_breakpoints[];
extern int g_num_tp_breakpoints;
extern word32 g_tp_breakpoints[];
extern Page_info page_info_rd_wr[];
@ -34,6 +43,8 @@ extern int g_rom_version;
extern int g_user_page2_shadow;
extern int g_parallel;
extern int g_ethernet_enabled;
char c;
/* from iwm.c */
int g_num_shadow_all_banks = 0;
@ -240,11 +251,48 @@ void moremem_init() {
void fixup_brks() {
word32 page;
word32 tmp, tmp2;
Pg_info val;
int is_wr_only;
int i, num;
int i;
/* need to clear break bit from all pages first? */
for (page = 0; page < 0xffff; ++page) {
val = GET_PAGE_INFO_RD(page);
val = (Pg_info)((ptrdiff_t)val &~ BANK_BREAK);
SET_PAGE_INFO_RD(page, val);
}
for (page = 0; page < 0xffff; ++page) {
val = GET_PAGE_INFO_WR(page);
val = (Pg_info)((ptrdiff_t)val &~ BANK_BREAK);
SET_PAGE_INFO_WR(page, val);
}
/* bp are read-only. mp are read/write */
for (i = 0; i < g_num_bp_breakpoints; ++i) {
page = (g_bp_breakpoints[i] >> 8) & 0xffff;
val = GET_PAGE_INFO_RD(page);
val = (Pg_info)((ptrdiff_t)val | BANK_BREAK);
SET_PAGE_INFO_RD(page, val);
/* why IO_TMP? */
}
for (i = 0; i < g_num_tp_breakpoints; ++i) {
page = (g_tp_breakpoints[i] >> 8) & 0xffff;
val = GET_PAGE_INFO_RD(page);
val = (Pg_info)((ptrdiff_t)val | BANK_BREAK);
SET_PAGE_INFO_RD(page, val);
/* why IO_TMP? */
}
for (i = 0; i < g_num_mp_breakpoints; ++i) {
page = (g_mp_breakpoints[i] >> 8) & 0xffff;
val = GET_PAGE_INFO_WR(page);
val = (Pg_info)((ptrdiff_t)val | BANK_BREAK);
SET_PAGE_INFO_WR(page, val);
/* why IO_TMP? */
}
#if 0
num = g_num_breakpoints;
for(i = 0; i < num; i++) {
page = (g_breakpts[i] >> 8) & 0xffff;
@ -260,6 +308,8 @@ void fixup_brks() {
tmp2 = tmp | BANK_IO_TMP | BANK_BREAK;
SET_PAGE_INFO_WR(page, val - tmp + tmp2);
}
#endif
}
void fixup_hires_on() {
@ -1591,7 +1641,7 @@ int io_read(word32 loc, double *cyc_ptr) {
//case 0xb8:
// return 0;
// break;
#ifdef HAVE_TFE
#ifdef HAVE_RAWNET
/*Uthernet read access on slot 3*/
case 0xb0:
case 0xb1:
@ -1609,8 +1659,8 @@ int io_read(word32 loc, double *cyc_ptr) {
case 0xbd:
case 0xbe:
case 0xbf:
if (tfe_enabled) {
return tfe_read((word16)loc & 0xf);
if (g_ethernet_enabled) {
return cs8900_read((word16)loc & 0xf);
}
else
{return 0;}
@ -2326,7 +2376,7 @@ void io_write(word32 loc, int val, double *cyc_ptr) {
//case 0xb8: case 0xb9: case 0xba: case 0xbb:
//case 0xbc: case 0xbd: case 0xbe: case 0xbf:
// UNIMPL_WRITE;
#ifdef HAVE_TFE
#ifdef HAVE_RAWNET
/*Uthernet write access on slot 3*/
case 0xb0:
case 0xb1:
@ -2344,9 +2394,9 @@ void io_write(word32 loc, int val, double *cyc_ptr) {
case 0xbd:
case 0xbe:
case 0xbf:
if (tfe_enabled)
if (g_ethernet_enabled)
{
tfe_store((word16)loc & 0xf, (byte)val);
cs8900_store((word16)loc & 0xf, (byte)val);
return;
}
else

View File

@ -8,10 +8,15 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include "options.h"
#include "glog.h"
#include "defc.h"
#ifdef _MSC_VER
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
// config is parsed in config.c :: config_parse_config_gsplus_file()
// cli is parsed here. would be nice to reuse some code
@ -62,6 +67,8 @@ extern int g_audio_enable; // defined in sound.c
// Start in fullscreen mode
extern int g_fullscreen; // defined in adb.c, because weird driver writing for x
extern int g_dbg_shell;
// Specify the joystick - SDL2
extern int g_joystick_number; // defined in joystick_driver.c
extern int g_joystick_x_axis; // defined in joystick_driver.c
@ -314,15 +321,6 @@ void parse_cli_options(int argc, char **argv) {
glogf("%s Setting scanline simulator darkness to %d%%", parse_log_prefix, tmp1);
g_scanline_simulator = tmp1;
i++;
} else if(!strcmp("-enet", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-enet' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as ethernet enable val", parse_log_prefix, tmp1);
g_ethernet = tmp1;
i++;
} else if(!strcmp("-x", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-x' missing argument", parse_log_prefix);
@ -386,6 +384,8 @@ void parse_cli_options(int argc, char **argv) {
g_dbg_enable_port = strtol(argv[i+1], 0, 0);
glogf("%s Using %d for debug port", parse_log_prefix, g_dbg_enable_port);
i++;
} else if (!strcmp("-g", argv[i])) {
g_dbg_shell = 1;
} else {
if ((i == (argc - 1)) && (strncmp("-", argv[i], 1) != 0)) {
final_arg = argv[i];
@ -421,7 +421,6 @@ void help_exit() {
printf(" -skip value Set skip_amt to value\n");
printf(" -audio value Set audio enable to value\n");
printf(" -arate value Set preferred audio rate to value\n");
printf(" -enet value Set ethernet to value\n");
printf(" -config value Set config file to value\n");
printf(" -debugport value Set debugport to value\n");
printf(" -ssdir value Set screenshot save directory to value\n");

View File

@ -172,9 +172,9 @@ void do_debug_intfc(void);
word32 dis_get_memory_ptr(word32 addr);
void show_one_toolset(FILE *toolfile, int toolnum, word32 addr);
void show_toolset_tables(word32 a2bank, word32 addr);
void set_bp(word32 addr);
void show_bp(void);
void delete_bp(word32 addr);
int set_bp(int type, word32 addr);
void show_bp(int type);
int delete_bp(int type, word32 addr);
void do_blank(void);
void do_go(void);
void do_go_debug(void); // socket debug ver
@ -385,7 +385,7 @@ double remove_event_scc(int type);
void show_all_events(void);
void show_pmhz(void);
void setup_zip_speeds(void);
void run_prog(void);
int run_prog(void);
void add_irq(word32 irq_mask);
void remove_irq(word32 irq_mask);
void take_irq(int is_it_brk);

28
src/rawnet/CMakeLists.txt Normal file
View File

@ -0,0 +1,28 @@
if(WIN32)
set(rawnetarch rawnetarch_win32.c)
elseif(APPLE)
set(rawnetarch rawnetarch_vmnet_helper.c)
#set(rawnetarch rawnetarch_unix.c)
elseif(UNIX)
set(rawnetarch rawnetarch_unix.c)
endif()
add_library(rawnet cs8900.c rawnet.c rawnetsupp.c rawnetarch.c ${rawnetarch})
target_compile_definitions(rawnet PUBLIC HAVE_RAWNET)
target_compile_definitions(rawnet PRIVATE CS8900_DEBUG RAWNET_DEBUG_FRAMES)
target_compile_options(rawnet PRIVATE -g)
if(WIN32)
target_link_libraries(rawnet ws2_32) # winsock2
elseif(APPLE)
#target_link_libraries(rawnet PRIVATE pcap)
#target_link_libraries(rawnet PRIVATE "-framework vmnet")
add_executable(vmnet_helper vmnet_helper.c)
target_link_libraries(vmnet_helper PRIVATE "-framework vmnet")
elseif(UNIX)
target_link_libraries(rawnet PRIVATE pcap)
endif()

35
src/rawnet/Networking.txt Normal file
View File

@ -0,0 +1,35 @@
Networking
----------
GS+ can emulate an Uthernet (the original) card in slot 3. Marinetti is supported with the Uthernet Link Layer. Version 1.0.2 or newer is recommended.
Configuration:
In the settings menu, select Ethernet Card Configuration.
Make sure Uthernet Card in Slot 3 is set to On.
Select the Interface menu to choose the selected interface from a menu.
Win32:
Ethernet support uses Winpcap or its modern successor, npcap. You need to install them.
Winpcap/npcap require a hardwired ethernet connection in promiscuous mode -- they work by tapping into the ethernet stream.
Interface names are not particularly meaningful. Sorry. Run `getmac /v` from cmd.exe to get a human friendly name for the interface device.
In marinetti, hardcode the ip address, gateway, and dns servers.
OS X:
Ethernet support uses the vmnet framework. This provides a virtual ethernet device, dhcp server, and dns server, all bridged to the Macintosh's network.
Unfortunately, vmnet requires root permissions or a codesigning entitlment which may only valid for applications through the Mac App Store.
In marinetti, use DHCP.
Linux:
Ethernet support uses the tap ethernet device. This require setting up the device and bridging it to your local network.

1675
src/rawnet/cs8900.c Normal file

File diff suppressed because it is too large Load Diff

64
src/rawnet/cs8900.h Normal file
View File

@ -0,0 +1,64 @@
/*
* cs8900.h - CS8900 Ethernet Core
*
* Written by
* Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include <stdint.h>
#ifndef HAVE_RAWNET
#error CS8900.H should not be included if HAVE_RAWNET is not defined!
#endif /* #ifdef HAVE_RAWNET */
#ifndef VICE_CS8900_H
#define VICE_CS8900_H
//#include <"types.h">
typedef struct snapshot_s snapshot_t;
extern int cs8900_snapshot_read_module(snapshot_t *s);
extern int cs8900_snapshot_write_module(snapshot_t *s);
extern int cs8900_init(void);
extern void cs8900_reset(void);
extern int cs8900_activate(const char *net_interface);
extern int cs8900_deactivate(void);
extern void cs8900_shutdown(void);
extern uint8_t cs8900_read(uint16_t io_address);
extern uint8_t cs8900_peek(uint16_t io_address);
extern void cs8900_store(uint16_t io_address, uint8_t byte);
extern int cs8900_dump(void);
/*
This is a helper for cs8900_receive() to determine if the received frame should be accepted
according to the settings.
This function is even allowed to be called (indirectly via rawnet_should_accept) in rawnetarch.c
from rawnet_arch_receive() if necessary, and must be registered using rawnet_set_should_accept_func
at init time.
*/
extern int cs8900_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index, int *pcorrect_mac, int *pbroadcast, int *pmulticast);
#endif

85
src/rawnet/rawnet.c Normal file
View File

@ -0,0 +1,85 @@
/*
* rawnet.c - raw ethernet interface
*
* Written by
* Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>
* Christian Vogelgsang <chris@vogelgsang.org>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
// #include "vice.h"
#ifdef HAVE_RAWNET
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "rawnet.h"
#include "rawnetsupp.h"
#include "rawnetarch.h"
static int (*should_accept)(unsigned char *, int, int *, int *, int *, int *, int *) = NULL;
int rawnet_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index, int *pcorrect_mac, int *pbroadcast, int *pmulticast)
{
assert(should_accept);
return should_accept(buffer, length, phashed, phash_index, pcorrect_mac, pbroadcast, pmulticast);
}
void rawnet_set_should_accept_func(int (*func)(unsigned char *, int, int *, int *, int *, int *, int *))
{
should_accept = func;
}
/* ------------------------------------------------------------------------- */
/* functions for selecting and querying available NICs */
int rawnet_enumadapter_open(void)
{
if (!rawnet_arch_enumadapter_open()) {
/* tfe_cannot_use = 1; */
return 0;
}
return 1;
}
int rawnet_enumadapter(char **ppname, char **ppdescription)
{
return rawnet_arch_enumadapter(ppname, ppdescription);
}
int rawnet_enumadapter_close(void)
{
return rawnet_arch_enumadapter_close();
}
char *rawnet_get_standard_interface(void)
{
return rawnet_arch_get_standard_interface();
}
int rawnet_status(void)
{
return rawnet_arch_status();
}
#endif /* #ifdef HAVE_RAWNET */

77
src/rawnet/rawnet.h Normal file
View File

@ -0,0 +1,77 @@
/*
* rawnet.h - raw ethernet interface
*
* Written by
* Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifdef HAVE_RAWNET
#else
#error RAWNET.H should not be included if HAVE_RAWNET is not defined!
#endif /* #ifdef HAVE_RAWNET */
#ifndef VICE_RAWNET_H
#define VICE_RAWNET_H
/*
This is a helper for the _receive() function of the emulated ethernet chip to determine
if the received frame should be accepted according to the settings.
This function is even allowed to be called in rawnetarch.c from rawnet_arch_receive() if
necessary. the respective helper function of the emulated ethernet chip must be registered
using rawnet_set_should_accept_func at init time.
*/
extern int rawnet_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index, int *pcorrect_mac, int *pbroadcast, int *pmulticast);
extern void rawnet_set_should_accept_func(int (*func)(unsigned char *, int, int *, int *, int *, int *, int *));
/*
These functions let the UI enumerate the available interfaces.
First, rawnet_enumadapter_open() is used to start enumeration.
rawnet_enumadapter() is then used to gather information for each adapter present
on the system, where:
ppname points to a pointer which will hold the name of the interface
ppdescription points to a pointer which will hold the description of the interface
For each of these parameters, new memory is allocated, so it has to be
freed with lib_free().
Note: The description can be NULL, since pcap_if_t.desc can be NULL, so
check the description before calling lib_free() on it.
rawnet_enumadapter_close() must be used to stop processing.
Each function returns 1 on success, and 0 on failure.
rawnet_enumadapter() only fails if there is no more adpater; in this case,
*ppname and *ppdescription are not altered.
*/
extern int rawnet_enumadapter_open(void);
extern int rawnet_enumadapter(char **ppname, char **ppdescription);
extern int rawnet_enumadapter_close(void);
extern char *rawnet_get_standard_interface(void);
extern int rawnet_status(void);
#endif

144
src/rawnet/rawnetarch.c Normal file
View File

@ -0,0 +1,144 @@
/** \file rawnetarch.c
* \brief raw ethernet interface, architecture-dependant stuff
*
* \author Bas Wassink <b.wassink@ziggo.nl
*/
/*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include "rawnetarch.h"
#include "rawnetsupp.h"
#include <assert.h>
#ifdef HAVE_RAWNET
/* backward compatibility junk */
/** \brief Transmit a frame
*
* \param[in] force Delete waiting frames in transmit buffer
* \param[in] onecoll Terminate after just one collision
* \param[in] inhibit_crc Do not append CRC to the transmission
* \param[in] tx_pad_dis Disable padding to 60 Bytes
* \param[in] txlength Frame length
* \param[in] txframe Pointer to the frame to be transmitted
*/
void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc,
int tx_pad_dis, int txlength, uint8_t *txframe)
{
int ok;
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log,
"rawnet_arch_transmit() called, with: force = %s, onecoll = %s, "
"inhibit_crc=%s, tx_pad_dis=%s, txlength=%u",
force ? "TRUE" : "FALSE",
onecoll ? "TRUE" : "FALSE",
inhibit_crc ? "TRUE" : "FALSE",
tx_pad_dis ? "TRUE" : "FALSE",
txlength);
#endif
ok = rawnet_arch_write(txframe, txlength);
if (ok < 0) {
log_message(rawnet_arch_log, "WARNING! Could not send packet!");
}
}
/**
* \brief Check if a frame was received
*
* This function checks if there was a frame received. If so, it returns 1,
* else 0.
*
* If there was no frame, none of the parameters is changed!
*
* If there was a frame, the following actions are done:
*
* - at maximum \a plen byte are transferred into the buffer given by \a pbuffer
* - \a plen gets the length of the received frame, EVEN if this is more
* than has been copied to \a pbuffer!
* - if the dest. address was accepted by the hash filter, \a phashed is set,
* else cleared.
* - if the dest. address was accepted by the hash filter, \a phash_index is
* set to the number of the rule leading to the acceptance
* - if the receive was ok (good CRC and valid length), \a *prx_ok is set, else
* cleared.
* - if the dest. address was accepted because it's exactly our MAC address
* (set by rawnet_arch_set_mac()), \a pcorrect_mac is set, else cleared.
* - if the dest. address was accepted since it was a broadcast address,
* \a pbroadcast is set, else cleared.
* - if the received frame had a crc error, \a pcrc_error is set, else cleared
*
* \param[out] buffer where to store a frame
* \param[in,out] plen IN: maximum length of frame to copy;
* OUT: length of received frame OUT
* can be bigger than IN if received frame was
* longer than supplied buffer
* \param[out] phashed set if the dest. address is accepted by the
* hash filter
* \param[out] phash_index hash table index if hashed == TRUE
* \param[out] prx_ok set if good CRC and valid length
* \param[out] pcorrect_mac set if dest. address is exactly our IA
* \param[out[ pbroadcast set if dest. address is a broadcast address
* \param[out] pcrc_error set if received frame had a CRC error
*/
int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed,
int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast,
int *pcrc_error)
{
int ok;
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log,
"rawnet_arch_receive() called, with *plen=%u.",
*plen);
#endif
assert((*plen & 1) == 0);
ok = rawnet_arch_read(pbuffer, *plen);
if (ok <= 0) return 0;
if (ok & 1) ++ok;
*plen = ok;
*phashed =
*phash_index =
*pbroadcast =
*pcorrect_mac =
*pcrc_error = 0;
/* this frame has been received correctly */
*prx_ok = 1;
return 1;
}
#endif /* ifdef HAVE_RAWNET */

77
src/rawnet/rawnetarch.h Normal file
View File

@ -0,0 +1,77 @@
/*
* rawnetarch.h - raw ethernet interface
* architecture-dependant stuff
*
* Written by
* Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include <stdint.h>
#ifdef HAVE_RAWNET
#else
#error RAWNETARCH.H should not be included if HAVE_RAWNET is not defined!
#endif /* #ifdef HAVE_RAWNET */
#ifndef VICE_RAWNETARCH_H
#define VICE_RAWNETARCH_H
/* define this only if VICE should write each and every frame received
and send into the VICE log
WARNING: The log grows very fast!
*/
/* #define RAWNET_DEBUG_FRAMES */
// #include "types.h"
extern int rawnet_arch_init(void);
extern void rawnet_arch_pre_reset(void);
extern void rawnet_arch_post_reset(void);
extern int rawnet_arch_activate(const char *interface_name);
extern void rawnet_arch_deactivate(void);
extern void rawnet_arch_set_mac(const uint8_t mac[6]);
extern void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]);
extern void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash);
extern void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver);
extern void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, int tx_pad_dis, int txlength, uint8_t *txframe);
extern int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast, int *pcrc_error);
extern int rawnet_arch_enumadapter_open(void);
extern int rawnet_arch_enumadapter(char **ppname, char **ppdescription);
extern int rawnet_arch_enumadapter_close(void);
extern char *rawnet_arch_get_standard_interface(void);
extern int rawnet_arch_read(void *buffer, int length);
extern int rawnet_arch_write(const void *buffer, int length);
extern int rawnet_arch_get_mtu(void);
extern int rawnet_arch_get_mac(uint8_t mac[6]);
extern int rawnet_arch_status(void);
#endif

481
src/rawnet/rawnetarch_tap.c Normal file
View File

@ -0,0 +1,481 @@
/* tun/tap support */
/* for Linux, *BSD */
/*
* tap is a virtual ethernet devices.
* open the device, configure, and read/write ethernet frames.
*
* Linux setup: (from Network Programmability and Automation, Appendix A)
*
* Notes:
* - this assumes eth0 is your main interface device
* - may need to install the iproute/iproute2 package (ip command)
* - do this stuff as root.
*
* 1. create a tap interface
* $ ip tuntap add tap65816 mode tap user YOUR_USER_NAME
* $ ip link set tap65816 up
*
* 2. create a network bridge
* $ ip link add name br0 type bridge
* $ ip link set br0 up
*
* 3. bridge the physical network and virtual network.
* $ ip link set eth0 master br0
* $ ip link set tap65816 master br0
*
* 4. remove ip address from physical device (This will kill networking)
* ip address flush dev eth0
*
* 5. and add the ip address to the bridge
* dhclient br0 # if using dhcp
* ip address add 192.168.1.1/24 dev eth0 # if using static ip address.
*
* *BSD:
* - assumes eth0 is your main interface device.
* $ ifconfig bridge0 create
* $ ifconfig tap65816 create
* $ ifconfig bridge0 addm eth0 addm tap65816 up
*
* allow normal users to open tap devices?
* $ sysctl net.link.tap.user_open=1
* $ sysctl net.link.tap.up_on_open=1
*
* set permissions
* $ chown YOUR_USER_NAME /dev/tap65816
* $ chmod 660 /dev/tap65816
*/
#define _GNU_SOURCE
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <net/if.h>
#include <dirent.h>
#if defined(__linux__)
#include <linux/if.h>
#include <linux/if_tun.h>
#endif
#include "rawnetarch.h"
#include "rawnetsupp.h"
#if defined(__linux__)
#define TAP_DEVICE "/dev/net/tun"
#endif
#if defined(__FreeBSD__)
#define TAP_DEVICE "/dev/tap"
#endif
static int interface_fd = -1;
static char *interface_dev = NULL;
static uint8_t interface_mac[6];
static uint8_t interface_fake_mac[6];
static uint8_t *interface_buffer = NULL;
static int interface_buffer_size = 0;
int rawnet_arch_init(void) {
interface_fd = -1;
return 1;
}
void rawnet_arch_pre_reset(void) {
/* NOP */
}
void rawnet_arch_post_reset(void) {
/* NOP */
}
/* memoized buffer for ethernet packets, etc */
static int make_buffer(int size) {
if (size <= interface_buffer_size) return 0;
if (interface_buffer) free(interface_buffer);
if (size < 1500) size = 1500; /* good mtu size */
interface_buffer_size = 0;
size *= 2;
interface_buffer = malloc(size);
if (!interface_buffer) return -1;
interface_buffer_size = size;
return 0;
}
#if defined(__linux__)
/* interface name. default is tap65816. */
int rawnet_arch_activate(const char *interface_name) {
struct ifreq ifr;
int ok;
int one = 1;
int fd;
if (!interface_name || !*interface_name) {
interface_name = "tap65816";
}
fd = open(TAP_DEVICE, O_RDWR);
if (fd < 0) {
fprintf(stderr, "rawnet_arch_activate: open(%s): %s\n", TAP_DEVICE, strerror(errno));
return 0;
}
ok = ioctl(fd, FIONBIO, &one);
if (ok < 0) {
perror("ioctl(FIONBIO");
close(fd);
return 0;
}
memset(&ifr, 0, sizeof(ifr));
strcpy(&if.ifr_name, interface_name);
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
ok = ioctl(fd, TUNSETIFF, (void *) &ifr);
if (ok < 0) {
perror("ioctl(TUNSETIFF)");
close(fd);
return 0;
}
if (rawnet_arch_get_mac(interface_mac) < 0) {
perror("rawnet_arch_get_mac");
close(fd);
return 0;
}
/* copy mac to fake mac */
memcpy(interface_fake_mac, interface_mac, 6);
interface_dev = strdup(interface_name);
interface_fd = fd;
return 1;
}
#endif
#if defined(__FreeBSD__)
/* man tap(4) */
/* interface name. default is tap65816. */
int rawnet_arch_activate(const char *interface_name) {
struct ifreq ifr;
int ok;
int one = 1;
int fd;
char *path[64];
if (!interface_name || !*interface_name) {
interface_name = "tap65816";
}
ok = snprintf(path, sizeof(path), "/dev/%s", interface_name);
if (ok >= sizeof(path)) return 0;
fd = open(path, O_RDWR);
if (fd < 0) {
fprintf(stderr, "rawnet_arch_activate: open(%s): %s\n", path, strerror(errno));
return 0;
}
ok = ioctl(fd, FIONBIO, &one);
if (ok < 0) {
perror("ioctl(FIONBIO");
close(fd);
return 0;
}
if (rawnet_arch_get_mac(interface_mac) < 0) {
perror("rawnet_arch_get_mac");
close(fd);
return 0;
}
/* copy mac to fake mac */
memcpy(interface_fake_mac, interface_mac, 6);
interface_dev = strdup(interface_name);
interface_fd = fd;
return 1;
}
#endif
void rawnet_arch_deactivate(void) {
if (interface_fd >= 0)
close(interface_fd);
free(interface_dev);
free(interface_buffer);
interface_buffer = 0;
interface_buffer_size = 0;
interface_dev = NULL;
interface_fd = -1;
}
void rawnet_arch_set_mac(const uint8_t mac[6]) {
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
#endif
memcpy(interface_fake_mac, mac, 6);
/* in theory, SIOCSIFHWADDR (linux) or SIOCSIFADDR (bsd) will set the mac address. */
/* in testing, (linux) I get EBUSY or EOPNOTSUPP */
#if 0
if (interface_fd < 0) return;
#if defined(__linux__)
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);
if (ioctl(interface_fd, SIOCSIFHWADDR, (void *)&ifr) < 0)
perror("ioctl(SIOCSIFHWADDR)");
#endif
#if defined(__FreeBSD__)
if (ioctl(interface_fd, SIOCSIFADDR, mac) < 0)
perror("ioctl(SIOCSIFADDR)");
#endif
#endif
}
void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) {
/* NOP */
}
void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) {
/* NOP */
}
void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) {
/* NOP */
}
int rawnet_arch_read(void *buffer, int nbyte) {
int ok;
if (make_buffer(nbyte) < 0) return -1;
ok = read(interface_fd, interface_buffer, nbyte);
if (ok <= 0) return -1;
rawnet_fix_incoming_packet(interface_buffer, ok, interface_mac, interface_fake_mac);
memcpy(buffer, interface_buffer, ok);
return ok;
}
int rawnet_arch_write(const void *buffer, int nbyte) {
int ok;
if (make_buffer(nbyte) < 0) return -1;
memcpy(interface_buffer, buffer, nbyte);
rawnet_fix_outgoing_packet(interface_buffer, nbyte, interface_mac, interface_fake_mac);
ok = write(interface_fd, interface_buffer, nbyte);
return ok;
}
static unsigned adapter_index = 0;
static unsigned adapter_count = 0;
static char **devices = NULL;
static int cmp(const void *a, const void *b) {
return strcasecmp(*(const char **)a, *(const char **)b);
}
int rawnet_arch_enumadapter_open(void) {
adapter_index = 0;
adapter_count = 0;
devices = NULL;
char buffer[MAXPATHLEN];
unsigned capacity = 0;
unsigned count = 0;
DIR *dp = NULL;
int i;
capacity = 20;
devices = (char **)malloc(sizeof(char *) * capacity);
if (!devices) return 0;
#if defined(__linux__)
dp = opendir("/sys/class/net/");
if (!dp) goto fail;
for(;;) {
char *cp;
FILE *fp;
struct dirent *d = readdir(dp);
if (!d) break;
if (d->d_name[0] == '.') continue;
sprintf(buffer, "/sys/class/net/%s/tun_flags", d->d_name);
fp = fopen(buffer, "r");
if (!fp) continue;
cp = fgets(buffer, sizeof(buffer), fp);
fclose(fp);
if (cp) {
/* expect 0x1002 */
int flags = strtol(cp, (char **)NULL, 16);
if ((flags & TUN_TYPE_MASK) == IFF_TAP) {
devices[count++] = strdup(d->d_name);
if (count == capacity) {
char **tmp;
capacity *= 2;
tmp = (char **)realloc(devices, sizeof(char *) * capacity);
if (tmp) devices = tmp;
else break; /* no mem? */
}
}
}
}
closedir(dp);
#endif
#if defined(__FreeBSD__)
/* dev/tapxxxx */
dp = opendir("/dev/");
if (!dp) goto fail;
for(;;) {
struct dirent *d = readdir(dp);
if (!d) break;
if (d->d_name[0] == '.') continue;
if (strncmp(d->d_name, "tap", 3) == 0 && isdigit(d->d_name[3])) {
devices[count++] = strdup(d->d_name);
if (count == capacity) {
char **tmp;
capacity *= 2;
tmp = (char **)realloc(devices, sizeof(char *) * capacity);
if (tmp) devices = tmp;
else break; /* no mem? */
}
}
}
closedir(dp);
#endif
/* sort them ... */
qsort(devices, count, sizeof(char *), cmp);
adapter_count = count;
return 1;
fail:
if (dp) closedir(dp);
if (devices) for(i = 0; i <count; ++i) free(devices[i]);
free(devices);
return 0;
}
int rawnet_arch_enumadapter_close(void) {
if (devices) {
int i;
for (i = 0; i < adapter_count; ++i)
free(devices[i]);
free(devices);
}
adapter_count = 0;
adapter_index = 0;
devices = NULL;
return 1;
}
int rawnet_arch_enumadapter(char **ppname, char **ppdescription) {
if (adapter_index >= adapter_count) return 0;
if (ppdescription) *ppdescription = NULL;
if (ppname) *ppname = strdup(devices[adapter_index]);
++adapter_index;
return 1;
}
char *rawnet_arch_get_standard_interface(void) {
return lib_stralloc("tap65816");
}
int rawnet_arch_get_mtu(void) {
if (interface_fd < 0) return -1;
#if defined(__linux__)
/* n.b. linux tap driver doesn't actually support SIOCGIFMTU */
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
if (ioctl(interface_fd, SIOCGIFMTU, (void *) &ifr) < 0) return -1; /* ? */
return ifr.ifr_mtu;
#endif
#if defined(__FreeBSD__)
struct tapinfo ti;
if (ioctl(interface_fd, TAPSIFINFO, &ti) < 0) return -1;
return ti.mtu;
#endif
return -1;
}
int rawnet_arch_get_mac(uint8_t mac[6]) {
if (interface_fd < 0) return -1;
#if defined(__linux__)
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
if (ioctl(interface_fd, SIOCGIFHWADDR, (void *)&ifr) < 0) return -1;
memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
return 0;
#endif
#if defined(__FreeBSD__)
if (ioctl(interface_fd, SIOCSIFADDR, mac) < 0) return -1;
return 0;
#endif
return -1;
}
int rawnet_arch_status(void) {
return interface_fd >= 0 ? 1 : 0;
}

View File

@ -0,0 +1,511 @@
/** \file rawnetarch_unix.c
* \brief Raw ethernet interface, architecture-dependent stuff
*
* \author Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>
* \author Bas Wassink <b.wassink@ziggo.nl>
*
* These functions let the UI enumerate the available interfaces.
*
* First, rawnet_arch_enumadapter_open() is used to start enumeration.
*
* rawnet_arch_enumadapter() is then used to gather information for each adapter
* present on the system, where:
*
* ppname points to a pointer which will hold the name of the interface
* ppdescription points to a pointer which will hold the description of the
* interface
*
* For each of these parameters, new memory is allocated, so it has to be
* freed with lib_free(), except ppdescription, which can be `NULL`, though
* calling lib_free() on `NULL` is safe.
*
* rawnet_arch_enumadapter_close() must be used to stop processing.
*
* Each function returns 1 on success, and 0 on failure.
* rawnet_arch_enumadapter() only fails if there is no more adpater; in this
* case, *ppname and *ppdescription are not altered.
*/
/*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include <stdint.h>
// #include "vice.h"
#ifdef HAVE_RAWNET
#include <pcap.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include "lib.h"
// #include "log.h"
#include "rawnetarch.h"
#include "rawnetsupp.h"
#if defined(__linux__)
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#endif
/*
* FIXME: rename all remaining tfe_ stuff to rawnet_
*/
#define RAWNET_DEBUG_WARN 1 /* this should not be deactivated
* If this should not be deactived, why is this
* here at all? --compyx
*/
/** \brief Only select devices that are PCAP_IF_UP
*
* Since on Linux pcap_findalldevs() returns all interfaces, including special
* kernal devices such as nfqueue, filtering the list returned by pcap makes
* sense. Should this filtering cause trouble on other Unices, this define can
* be guarded with #ifdef SOME_UNIX_VERSION to disable the filtering.
*/
#ifdef PCAP_IF_UP
#define RAWNET_ONLY_IF_UP
#endif
/** #define RAWNET_DEBUG_ARCH 1 **/
/** #define RAWNET_DEBUG_PKTDUMP 1 **/
/* ------------------------------------------------------------------------- */
/* variables needed */
// static log_t rawnet_arch_log = LOG_ERR;
/** \brief Iterator for the list returned by pcap_findalldevs()
*/
static pcap_if_t *rawnet_pcap_dev_iter = NULL;
/** \brief Device list returned by pcap_findalldevs()
*
* Can be `NULL` since pcap_findalldevs() considers not finding any devices a
* succesful outcome.
*/
static pcap_if_t *rawnet_pcap_dev_list = NULL;
static pcap_t *rawnet_pcap_fp = NULL;
static char *rawnet_device_name = NULL;
/** \brief Buffer for pcap error messages
*/
static char rawnet_pcap_errbuf[PCAP_ERRBUF_SIZE];
#ifdef RAWNET_DEBUG_PKTDUMP
static void debug_output( const char *text, uint8_t *what, int count )
{
char buffer[256];
char *p = buffer;
char *pbuffer1 = what;
int len1 = count;
int i;
sprintf(buffer, "\n%s: length = %u\n", text, len1);
fprintf(stderr, "%s", buffer);
do {
p = buffer;
for (i=0; (i<8) && len1>0; len1--, i++) {
sprintf(p, "%02x ", (unsigned int)(unsigned char)*pbuffer1++);
p += 3;
}
*(p-1) = '\n'; *p = 0;
fprintf(stderr, "%s", buffer);
} while (len1>0);
}
#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */
int rawnet_arch_enumadapter_open(void)
{
if (pcap_findalldevs(&rawnet_pcap_dev_list, rawnet_pcap_errbuf) == -1) {
log_message(rawnet_arch_log,
"ERROR in rawnet_arch_enumadapter_open: pcap_findalldevs: '%s'",
rawnet_pcap_errbuf);
return 0;
}
if (!rawnet_pcap_dev_list) {
log_message(rawnet_arch_log,
"ERROR in rawnet_arch_enumadapter_open, finding all pcap "
"devices - Do we have the necessary privilege rights?");
return 0;
}
rawnet_pcap_dev_iter = rawnet_pcap_dev_list;
return 1;
}
/** \brief Get current pcap device iterator values
*
* The \a ppname and \a ppdescription are heap-allocated via lib_stralloc()
* and should thus be freed after use with lib_free(). Please not that
* \a ppdescription can be `NULL` due to pcap_if_t->description being `NULL`,
* so check against `NULL` before using it. Calling lib_free() on it is safe
* though, free(`NULL`) is guaranteed to just do nothing.
*
* \param[out] ppname device name
* \param[out] ppdescription device description
*
* \return bool (1 on success, 0 on failure)
*/
int rawnet_arch_enumadapter(char **ppname, char **ppdescription)
{
#ifdef RAWNET_ONLY_IF_UP
/* only select devices that are up */
while (rawnet_pcap_dev_iter != NULL
&& !(rawnet_pcap_dev_iter->flags & PCAP_IF_UP)) {
rawnet_pcap_dev_iter = rawnet_pcap_dev_iter->next;
}
#endif
if (rawnet_pcap_dev_iter == NULL) {
return 0;
}
*ppname = lib_stralloc(rawnet_pcap_dev_iter->name);
/* carefull: pcap_if_t->description can be NULL and lib_stralloc() fails on
* passing `NULL` */
if (rawnet_pcap_dev_iter->description != NULL) {
*ppdescription = lib_stralloc(rawnet_pcap_dev_iter->description);
} else {
*ppdescription = NULL;
}
rawnet_pcap_dev_iter = rawnet_pcap_dev_iter->next;
return 1;
}
int rawnet_arch_enumadapter_close(void)
{
if (rawnet_pcap_dev_list) {
pcap_freealldevs(rawnet_pcap_dev_list);
rawnet_pcap_dev_list = NULL;
}
return 1;
}
static int rawnet_pcap_open_adapter(const char *interface_name)
{
rawnet_pcap_fp = pcap_open_live((char*)interface_name, 1700, 1, 20, rawnet_pcap_errbuf);
if ( rawnet_pcap_fp == NULL) {
log_message(rawnet_arch_log, "ERROR opening adapter: '%s'", rawnet_pcap_errbuf);
return 0;
}
if (pcap_setnonblock(rawnet_pcap_fp, 1, rawnet_pcap_errbuf) < 0) {
log_message(rawnet_arch_log, "WARNING: Setting PCAP to non-blocking failed: '%s'", rawnet_pcap_errbuf);
}
/* Check the link layer. We support only Ethernet for simplicity. */
if (pcap_datalink(rawnet_pcap_fp) != DLT_EN10MB) {
log_message(rawnet_arch_log, "ERROR: TFE works only on Ethernet networks.");
pcap_close(rawnet_pcap_fp);
rawnet_pcap_fp = NULL;
return 0;
}
rawnet_device_name = strdup(interface_name);
return 1;
}
/* ------------------------------------------------------------------------- */
/* the architecture-dependend functions */
int rawnet_arch_init(void)
{
//rawnet_arch_log = log_open("TFEARCH");
return 1;
}
void rawnet_arch_pre_reset(void)
{
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "rawnet_arch_pre_reset()." );
#endif
}
void rawnet_arch_post_reset(void)
{
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "rawnet_arch_post_reset()." );
#endif
}
int rawnet_arch_activate(const char *interface_name)
{
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "rawnet_arch_activate()." );
#endif
if (!rawnet_pcap_open_adapter(interface_name)) {
return 0;
}
return 1;
}
void rawnet_arch_deactivate( void )
{
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "rawnet_arch_deactivate()." );
#endif
}
void rawnet_arch_set_mac( const uint8_t mac[6] )
{
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
#endif
}
void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2])
{
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "New hash filter set: %08X:%08X.", hash_mask[1], hash_mask[0]);
#endif
}
/* int bBroadcast - broadcast */
/* int bIA - individual address (IA) */
/* int bMulticast - multicast if address passes the hash filter */
/* int bCorrect - accept correct frames */
/* int bPromiscuous - promiscuous mode */
/* int bIAHash - accept if IA passes the hash filter */
void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash)
{
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log, "rawnet_arch_recv_ctl() called with the following parameters:" );
log_message(rawnet_arch_log, "\tbBroadcast = %s", bBroadcast ? "TRUE" : "FALSE");
log_message(rawnet_arch_log, "\tbIA = %s", bIA ? "TRUE" : "FALSE");
log_message(rawnet_arch_log, "\tbMulticast = %s", bMulticast ? "TRUE" : "FALSE");
log_message(rawnet_arch_log, "\tbCorrect = %s", bCorrect ? "TRUE" : "FALSE");
log_message(rawnet_arch_log, "\tbPromiscuous = %s", bPromiscuous ? "TRUE" : "FALSE");
log_message(rawnet_arch_log, "\tbIAHash = %s", bIAHash ? "TRUE" : "FALSE");
#endif
}
void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver )
{
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log,
"rawnet_arch_line_ctl() called with the following parameters:");
log_message(rawnet_arch_log,
"\tbEnableTransmitter = %s", bEnableTransmitter ? "TRUE" : "FALSE");
log_message(rawnet_arch_log,
"\tbEnableReceiver = %s", bEnableReceiver ? "TRUE" : "FALSE");
#endif
}
/** \brief Raw pcap packet
*/
typedef struct rawnet_pcap_internal_s {
unsigned int len; /**< length of packet data */
uint8_t *buffer; /**< packet data */
} rawnet_pcap_internal_t;
/** \brief Callback function invoked by libpcap for every incoming packet
*
* \param[in,out] param reference to internal VICE packet struct
* \param[in] header pcap header
* \param[in] pkt_data packet data
*/
static void rawnet_pcap_packet_handler(u_char *param,
const struct pcap_pkthdr *header, const u_char *pkt_data)
{
rawnet_pcap_internal_t *pinternal = (void*)param;
/* determine the count of bytes which has been returned,
* but make sure not to overrun the buffer
*/
if (header->caplen < pinternal->len) {
pinternal->len = header->caplen;
}
memcpy(pinternal->buffer, pkt_data, pinternal->len);
}
/** \brief Receives a frame
*
* If there's none, it returns a -1 in \a pinternal->len, if there is one,
* it returns the length of the frame in bytes in \a pinternal->len.
*
* It copies the frame to \a buffer and returns the number of copied bytes as
* the return value.
*
* \param[in,out] pinternal internal VICE packet struct
*
* \note At most 'len' bytes are copied.
*
* \return number of bytes copied or -1 on failure
*/
static int rawnet_arch_receive_frame(rawnet_pcap_internal_t *pinternal)
{
int ret = -1;
/* check if there is something to receive */
if (pcap_dispatch(rawnet_pcap_fp, 1, rawnet_pcap_packet_handler,
(void*)pinternal) != 0) {
/* Something has been received */
ret = pinternal->len;
}
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log,
"rawnet_arch_receive_frame() called, returns %d.", ret);
#endif
return ret;
}
int rawnet_arch_read(void *buffer, int nbyte) {
int len;
rawnet_pcap_internal_t internal = { nbyte, (uint8_t *)buffer };
len = rawnet_arch_receive_frame(&internal);
if (len <= 0) return len;
#ifdef RAWNET_DEBUG_PKTDUMP
debug_output("Received frame: ", internal.buffer, internal.len);
#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */
return len;
}
int rawnet_arch_write(const void *buffer, int nbyte) {
#ifdef RAWNET_DEBUG_PKTDUMP
debug_output("Transmit frame: ", buffer, nbyte);
#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */
if (pcap_sendpacket(rawnet_pcap_fp, buffer, nbyte) < 0) {
log_message(rawnet_arch_log, "WARNING! Could not send packet!");
return -1;
}
return nbyte;
}
/** \brief Find default device on which to capture
*
* \return name of standard interface
*
* \note pcap_lookupdev() has been deprecated, so the correct way to get
* the default device is to use the first entry returned by
* pcap_findalldevs().
* See http://www.tcpdump.org/manpages/pcap_lookupdev.3pcap.html
*
* \return default interface name or `NULL` when not found
*
* \note free the returned value with lib_free() if not `NULL`
*/
char *rawnet_arch_get_standard_interface(void)
{
char *dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *list;
if (pcap_findalldevs(&list, errbuf) == 0 && list != NULL) {
dev = lib_stralloc(list[0].name);
pcap_freealldevs(list);
}
return dev;
}
extern int rawnet_arch_get_mtu(void) {
#if defined(__linux__)
int fd;
int ok;
struct ifreq ifr;
if (!rawnet_device_name) return -1;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) return -1;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, rawnet_device_name);
ok = ioctl(fd, SIOCGIFMTU, (void *)&ifr);
close(fd);
if (ok < 0) return -1;
return ifr.ifr_mtu;
#endif
return -1;
}
extern int rawnet_arch_get_mac(uint8_t mac[6]) {
#if defined(__linux__)
int fd;
struct ifreq ifr;
int ok;
if (!rawnet_device_name) return -1;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) return -1;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, rawnet_device_name);
ok = ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
if (ok < 0) return -1;
memcpy(mac, &ifr.ifr_hwaddr.sa_data, 6);
return 0;
#endif
return -1;
}
int rawnet_arch_status(void) {
return rawnet_pcap_fp ? 1 : 0;
}
#endif /* #ifdef HAVE_RAWNET */

View File

@ -0,0 +1,281 @@
/*
* OS X 10.10+
* vmnet support (clang -framework vmnet -framework Foundation)
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <vmnet/vmnet.h>
#include "rawnetarch.h"
#include "rawnetsupp.h"
static interface_ref interface;
static uint8_t interface_mac[6];
static uint8_t interface_fake_mac[6];
static uint64_t interface_mtu;
static uint64_t interface_packet_size;
static uint8_t *interface_buffer = NULL;
static vmnet_return_t interface_status;
int rawnet_arch_init(void) {
interface = NULL;
return 1;
}
void rawnet_arch_pre_reset(void) {
/* NOP */
}
void rawnet_arch_post_reset(void) {
/* NOP */
}
int rawnet_arch_activate(const char *interface_name) {
xpc_object_t dict;
dispatch_queue_t q;
dispatch_semaphore_t sem;
/*
* there's no way to set the MAC address directly.
* using vmnet_interface_id_key w/ the previous interface id
* *MIGHT* re-use the previous MAC address.
*/
if (interface) return 1;
memset(interface_mac, 0, sizeof(interface_mac));
memset(interface_fake_mac, 0, sizeof(interface_fake_mac));
interface_status = 0;
interface_mtu = 0;
interface_packet_size = 0;
dict = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(dict, vmnet_operation_mode_key, VMNET_SHARED_MODE);
sem = dispatch_semaphore_create(0);
q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
interface = vmnet_start_interface(dict, q, ^(vmnet_return_t status, xpc_object_t params){
interface_status = status;
if (status == VMNET_SUCCESS) {
const char *cp;
cp = xpc_dictionary_get_string(params, vmnet_mac_address_key);
fprintf(stderr, "vmnet mac: %s\n", cp);
sscanf(cp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&interface_mac[0],
&interface_mac[1],
&interface_mac[2],
&interface_mac[3],
&interface_mac[4],
&interface_mac[5]
);
interface_mtu = xpc_dictionary_get_uint64(params, vmnet_mtu_key);
interface_packet_size = xpc_dictionary_get_uint64(params, vmnet_max_packet_size_key);
fprintf(stderr, "vmnet mtu: %u\n", (unsigned)interface_mtu);
}
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
if (interface_status == VMNET_SUCCESS) {
interface_buffer = (uint8_t *)malloc(interface_packet_size);
/* copy mac to fake mac */
memcpy(interface_fake_mac, interface_mac, 6);
} else {
log_message(rawnet_arch_log, "vmnet_start_interface failed");
if (interface) {
vmnet_stop_interface(interface, q, ^(vmnet_return_t status){
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
interface = NULL;
}
}
dispatch_release(sem);
xpc_release(dict);
return interface_status == VMNET_SUCCESS;
}
void rawnet_arch_deactivate(void) {
dispatch_queue_t q;
dispatch_semaphore_t sem;
if (interface) {
sem = dispatch_semaphore_create(0);
q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
vmnet_stop_interface(interface, q, ^(vmnet_return_t status){
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_release(sem);
interface = NULL;
interface_status = 0;
}
free(interface_buffer);
interface_buffer = NULL;
}
void rawnet_arch_set_mac(const uint8_t mac[6]) {
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
#endif
memcpy(interface_fake_mac, mac, 6);
}
void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) {
/* NOP */
}
void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) {
/* NOP */
}
void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) {
/* NOP */
}
int rawnet_arch_read(void *buffer, int nbyte) {
int count = 1;
int xfer;
vmnet_return_t st;
struct vmpktdesc v;
struct iovec iov;
iov.iov_base = interface_buffer;
iov.iov_len = interface_packet_size;
v.vm_pkt_size = interface_packet_size;
v.vm_pkt_iov = &iov;
v.vm_pkt_iovcnt = 1;
v.vm_flags = 0;
st = vmnet_read(interface, &v, &count);
if (st != VMNET_SUCCESS) {
log_message(rawnet_arch_log, "vmnet_read failed!");
return -1;
}
if (count < 1) {
return 0;
}
rawnet_fix_incoming_packet(interface_buffer, v.vm_pkt_size, interface_mac, interface_fake_mac);
// iov.iov_len is not updated with the read count, apparently.
/* don't sebug multicast packets */
if (interface_buffer[0] == 0xff || (interface_buffer[0] & 0x01) == 0 ) {
fprintf(stderr, "\nrawnet_arch_receive: %u\n", (unsigned)v.vm_pkt_size);
rawnet_hexdump(interface_buffer, v.vm_pkt_size);
}
xfer = v.vm_pkt_size;
memcpy(buffer, interface_buffer, xfer);
return xfer;
}
int rawnet_arch_write(const void *buffer, int nbyte) {
int count = 1;
vmnet_return_t st;
struct vmpktdesc v;
struct iovec iov;
if (nbyte <= 0) return 0;
if (nbyte > interface_packet_size) {
log_message(rawnet_arch_log, "packet is too big: %d", nbyte);
return -1;
}
/* copy the buffer and fix the source mac address. */
memcpy(interface_buffer, buffer, nbyte);
rawnet_fix_outgoing_packet(interface_buffer, nbyte, interface_mac, interface_fake_mac);
iov.iov_base = interface_buffer;
iov.iov_len = nbyte;
v.vm_pkt_size = nbyte;
v.vm_pkt_iov = &iov;
v.vm_pkt_iovcnt = 1;
v.vm_flags = 0;
fprintf(stderr, "\nrawnet_arch_transmit: %u\n", (unsigned)iov.iov_len);
rawnet_hexdump(interface_buffer, v.vm_pkt_size);
st = vmnet_write(interface, &v, &count);
if (st != VMNET_SUCCESS) {
log_message(rawnet_arch_log, "vmnet_write failed!");
return -1;
}
return nbyte;
}
static unsigned adapter_index = 0;
int rawnet_arch_enumadapter_open(void) {
adapter_index = 0;
return 1;
}
int rawnet_arch_enumadapter(char **ppname, char **ppdescription) {
if (adapter_index == 0) {
++adapter_index;
if (ppname) *ppname = lib_stralloc("vmnet");
if (ppdescription) *ppdescription = lib_stralloc("vmnet");
return 1;
}
return 0;
}
int rawnet_arch_enumadapter_close(void) {
return 1;
}
char *rawnet_arch_get_standard_interface(void) {
return lib_stralloc("vmnet");
}
int rawnet_arch_get_mtu(void) {
return interface ? interface_mtu : -1;
}
int rawnet_arch_get_mac(uint8_t mac[6]) {
if (interface) {
memcpy(mac, interface_mac, 6);
return 1;
}
return -1;
}
int rawnet_arch_status(void) {
return interface ? 1 : 0;
}

View File

@ -0,0 +1,486 @@
/*
* OS X 10.10+
* vmnet support (clang -framework vmnet -framework Foundation)
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <errno.h>
#include <spawn.h>
#include <err.h>
#include <signal.h>
#include <mach-o/dyld.h>
#include "rawnetarch.h"
#include "rawnetsupp.h"
enum {
MSG_QUIT,
MSG_STATUS,
MSG_READ,
MSG_WRITE
};
#define MAKE_MSG(msg, extra) (msg | ((extra) << 8))
static uint8_t interface_mac[6];
static uint8_t interface_fake_mac[6];
static uint32_t interface_mtu;
static uint32_t interface_packet_size;
static uint8_t *interface_buffer = NULL;
static pid_t interface_pid = 0;
static int interface_pipe[2];
static pid_t safe_waitpid(pid_t pid, int *stat_loc, int options) {
for(;;) {
pid_t rv = waitpid(pid, stat_loc,options);
if (rv < 0 && errno == EINTR) continue;
return rv;
}
}
static ssize_t safe_read(void *data, size_t nbytes) {
for (;;) {
ssize_t rv = read(interface_pipe[0], data, nbytes);
if (rv < 0 && errno == EINTR) continue;
return rv;
}
}
static ssize_t safe_readv(const struct iovec *iov, int iovcnt) {
for(;;) {
ssize_t rv = readv(interface_pipe[0], iov, iovcnt);
if (rv < 0 && errno == EINTR) continue;
return rv;
}
}
static ssize_t safe_write(const void *data, size_t nbytes) {
for (;;) {
ssize_t rv = write(interface_pipe[1], data, nbytes);
if (rv < 0 && errno == EINTR) continue;
return rv;
}
}
static ssize_t safe_writev(const struct iovec *iov, int iovcnt) {
for(;;) {
ssize_t rv = writev(interface_pipe[1], iov, iovcnt);
if (rv < 0 && errno == EINTR) continue;
return rv;
}
}
/* block the sigpipe signal */
static int block_pipe(struct sigaction *oact) {
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = SIG_IGN;
act.sa_flags = SA_RESTART;
return sigaction(SIGPIPE, &act, oact);
}
static int restore_pipe(const struct sigaction *oact) {
return sigaction(SIGPIPE, oact, NULL);
}
#if 0
static int block_pipe(sigset_t *oldset) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
sigaddset(&set, SIGCHLD);
return sigprocmask(SIG_BLOCK, &set, oldset);
}
#endif
static int check_child_status(void) {
pid_t pid;
int stat;
pid = safe_waitpid(interface_pid, &stat, WNOHANG);
if (pid < 0 && errno == ECHILD) {
fprintf(stderr, "child process does not exist.\n");
close(interface_pipe[0]);
close(interface_pipe[1]);
interface_pid = 0;
return 0;
}
if (pid == interface_pid) {
if (WIFEXITED(stat)) fprintf(stderr, "child process exited.\n");
if (WIFSIGNALED(stat)) fprintf(stderr, "child process signalled.\n");
close(interface_pipe[0]);
close(interface_pipe[1]);
interface_pid = 0;
return 0;
}
return 1;
}
static char *get_relative_path(const char *leaf) {
uint32_t size = 0;
char *buffer = 0;
int ok;
char *cp;
int l;
l = strlen(leaf);
ok = _NSGetExecutablePath(NULL, &size);
size += l + 1;
buffer = malloc(size);
if (buffer) {
ok = _NSGetExecutablePath(buffer, &size);
if (ok < 0) {
free(buffer);
return NULL;
}
cp = strrchr(buffer, '/');
if (cp)
strcpy(cp + 1 , leaf);
else {
free(buffer);
buffer = NULL;
}
}
return buffer;
}
int rawnet_arch_init(void) {
//interface = NULL;
return 1;
}
void rawnet_arch_pre_reset(void) {
/* NOP */
}
void rawnet_arch_post_reset(void) {
/* NOP */
}
int rawnet_arch_activate(const char *interface_name) {
int ok;
posix_spawn_file_actions_t actions;
posix_spawnattr_t attr;
char *argv[] = { "vmnet_helper", NULL };
char *path = NULL;
int pipe_stdin[2];
int pipe_stdout[2];
struct sigaction oldaction;
if (interface_pid > 0) return 1;
/* fd[0] = read, fd[1] = write */
ok = pipe(pipe_stdin);
if (ok < 0) { warn("pipe"); return 0; }
ok = pipe(pipe_stdout);
if (ok < 0) { warn("pipe"); return 0; }
block_pipe(&oldaction);
posix_spawn_file_actions_init(&actions);
posix_spawnattr_init(&attr);
posix_spawn_file_actions_adddup2(&actions, pipe_stdin[0], STDIN_FILENO);
posix_spawn_file_actions_adddup2(&actions, pipe_stdout[1], STDOUT_FILENO);
posix_spawn_file_actions_addclose(&actions, pipe_stdin[0]);
posix_spawn_file_actions_addclose(&actions, pipe_stdin[1]);
posix_spawn_file_actions_addclose(&actions, pipe_stdout[0]);
posix_spawn_file_actions_addclose(&actions, pipe_stdout[1]);
path = get_relative_path("vmnet_helper");
ok = posix_spawn(&interface_pid, path, &actions, &attr, argv, NULL);
free(path);
posix_spawn_file_actions_destroy(&actions);
posix_spawnattr_destroy(&attr);
close(pipe_stdin[0]);
close(pipe_stdout[1]);
/* posix spawn returns 0 on success, error code on failure. */
if (ok != 0) {
fprintf(stderr, "posix_spawn vmnet_helper failed: %d\n", ok);
close(pipe_stdin[1]);
close(pipe_stdout[0]);
interface_pid = -1;
return 0;
}
interface_pipe[0] = pipe_stdout[0];
interface_pipe[1] = pipe_stdin[1];
/* now get the mac/mtu/etc */
uint32_t msg = MAKE_MSG(MSG_STATUS, 0);
ok = safe_write(&msg, 4);
if (ok != 4) goto fail;
ok = safe_read(&msg, 4);
if (ok != 4) goto fail;
if (msg != MAKE_MSG(MSG_STATUS, 6 + 4 + 4)) goto fail;
struct iovec iov[3];
iov[0].iov_len = 6;
iov[0].iov_base = interface_mac;
iov[1].iov_len = 4;
iov[1].iov_base = &interface_mtu;
iov[2].iov_len = 4;
iov[2].iov_base = &interface_packet_size;
ok = safe_readv(iov, 3);
if (ok != 6 + 4 + 4) goto fail;
/* copy mac to fake mac */
memcpy(interface_fake_mac, interface_mac, 6);
/* sanity check */
/* expect MTU = 1500, packet_size = 1518 */
if (interface_packet_size < 256) {
interface_packet_size = 1518;
}
interface_buffer = malloc(interface_packet_size);
if (!interface_buffer) goto fail;
restore_pipe(&oldaction);
return 1;
fail:
close(interface_pipe[0]);
close(interface_pipe[1]);
safe_waitpid(interface_pid, NULL, 0);
interface_pid = 0;
restore_pipe(&oldaction);
return 0;
}
void rawnet_arch_deactivate(void) {
if (interface_pid) {
close(interface_pipe[0]);
close(interface_pipe[1]);
for(;;) {
int ok = waitpid(interface_pid, NULL, 0);
if (ok < 0 && errno == EINTR) continue;
break;
}
interface_pid = 0;
}
free(interface_buffer);
interface_buffer = NULL;
}
void rawnet_arch_set_mac(const uint8_t mac[6]) {
#ifdef RAWNET_DEBUG_ARCH
log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
#endif
memcpy(interface_fake_mac, mac, 6);
}
void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) {
/* NOP */
}
void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) {
/* NOP */
}
void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) {
/* NOP */
}
int rawnet_arch_read(void *buffer, int nbyte) {
uint32_t msg;
int ok;
int xfer;
struct sigaction oldaction;
if (interface_pid <= 0) return -1;
block_pipe(&oldaction);
msg = MAKE_MSG(MSG_READ, 0);
ok = safe_write(&msg, 4);
if (ok != 4) goto fail;
ok = safe_read(&msg, 4);
if (ok != 4) goto fail;
if ((msg & 0xff) != MSG_READ) goto fail;
xfer = msg >> 8;
if (xfer > interface_packet_size) {
fprintf(stderr, "packet size too big: %d\n", xfer);
/* drain the message ... */
while (xfer) {
int count = interface_packet_size;
if (count > xfer) count = xfer;
ok = safe_read(interface_buffer, count);
if (ok < 0) goto fail;
xfer -= ok;
}
return -1;
}
if (xfer == 0) return -1;
ok = safe_read(interface_buffer, xfer);
if (ok != xfer) goto fail;
rawnet_fix_incoming_packet(interface_buffer, xfer, interface_mac, interface_fake_mac);
/* don't sebug multicast packets */
if (interface_buffer[0] == 0xff || (interface_buffer[0] & 0x01) == 0 ) {
fprintf(stderr, "\nrawnet_arch_receive: %u\n", (unsigned)xfer);
rawnet_hexdump(interface_buffer, xfer);
}
if (xfer > nbyte) xfer = nbyte;
memcpy(buffer, interface_buffer, xfer);
restore_pipe(&oldaction);
return xfer;
fail:
/* check if process still ok? */
check_child_status();
restore_pipe(&oldaction);
return -1;
}
int rawnet_arch_write(const void *buffer, int nbyte) {
int ok;
uint32_t msg;
struct iovec iov[2];
struct sigaction oldaction;
if (interface_pid <= 0) return -1;
if (nbyte <= 0) return 0;
if (nbyte > interface_packet_size) {
log_message(rawnet_arch_log, "packet is too big: %d", nbyte);
return -1;
}
/* copy the buffer and fix the source mac address. */
memcpy(interface_buffer, buffer, nbyte);
rawnet_fix_outgoing_packet(interface_buffer, nbyte, interface_mac, interface_fake_mac);
fprintf(stderr, "\nrawnet_arch_transmit: %u\n", (unsigned)nbyte);
rawnet_hexdump(interface_buffer, nbyte);
block_pipe(&oldaction);
msg = MAKE_MSG(MSG_WRITE, nbyte);
iov[0].iov_base = &msg;
iov[0].iov_len = 4;
iov[1].iov_base = interface_buffer;
iov[1].iov_len = nbyte;
ok = safe_writev(iov, 2);
if (ok != 4 + nbyte) goto fail;
ok = safe_read(&msg, 4);
if (ok != 4) goto fail;
if (msg != MAKE_MSG(MSG_WRITE, nbyte)) goto fail;
restore_pipe(&oldaction);
return nbyte;
fail:
check_child_status();
restore_pipe(&oldaction);
return -1;
}
static unsigned adapter_index = 0;
int rawnet_arch_enumadapter_open(void) {
adapter_index = 0;
return 1;
}
int rawnet_arch_enumadapter(char **ppname, char **ppdescription) {
if (adapter_index == 0) {
++adapter_index;
if (ppname) *ppname = lib_stralloc("vmnet");
if (ppdescription) *ppdescription = lib_stralloc("vmnet");
return 1;
}
return 0;
}
int rawnet_arch_enumadapter_close(void) {
return 1;
}
char *rawnet_arch_get_standard_interface(void) {
return lib_stralloc("vmnet");
}
int rawnet_arch_get_mtu(void) {
return interface_pid > 0 ? interface_mtu : -1;
}
int rawnet_arch_get_mac(uint8_t mac[6]) {
if (interface_pid > 0) {
memcpy(mac, interface_mac, 6);
return 1;
}
return -1;
}
int rawnet_arch_status(void) {
return interface_pid > 0 ? 1 : 0;
}

View File

@ -0,0 +1,579 @@
/** \file rawnetarch_win32.c
* \brief Raw ethernet interface, Win32 stuff
*
* \author Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>
*/
/*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
// #include "vice.h"
#ifdef HAVE_RAWNET
/* #define WPCAP */
#include <pcap.h>
/* prevent bpf redeclaration in packet32 */
#ifndef BPF_MAJOR_VERSION
#define BPF_MAJOR_VERSION
#endif
#include <Packet32.h>
#include <Windows.h>
#include <Ntddndis.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include "lib.h"
// #include "log.h"
#include "rawnet.h"
#include "rawnetarch.h"
#include "rawnetsupp.h"
typedef pcap_t *(*pcap_open_live_t)(const char *, int, int, int, char *);
typedef void *(*pcap_close_t)(pcap_t *);
typedef int (*pcap_dispatch_t)(pcap_t *, int, pcap_handler, u_char *);
typedef int (*pcap_setnonblock_t)(pcap_t *, int, char *);
typedef int (*pcap_datalink_t)(pcap_t *);
typedef int (*pcap_findalldevs_t)(pcap_if_t **, char *);
typedef void (*pcap_freealldevs_t)(pcap_if_t *);
typedef int (*pcap_sendpacket_t)(pcap_t *p, u_char *buf, int size);
typedef char *(*pcap_lookupdev_t)(char *);
typedef VOID (*PacketCloseAdapter_t)(LPADAPTER lpAdapter);
typedef LPADAPTER (*PacketOpenAdapter_t)(PCHAR AdapterName);
typedef BOOLEAN (*PacketSendPacket_t)(LPADAPTER AdapterObject, LPPACKET pPacket, BOOLEAN Sync);
typedef BOOLEAN (*PacketRequest_t)(LPADAPTER AdapterObject, BOOLEAN Set, PPACKET_OID_DATA OidData);
/** #define RAWNET_DEBUG_ARCH 1 **/
/** #define RAWNET_DEBUG_PKTDUMP 1 **/
/* #define RAWNET_DEBUG_FRAMES - might be defined in rawnetarch.h ! */
#define RAWNET_DEBUG_WARN 1 /* this should not be deactivated */
static pcap_open_live_t p_pcap_open_live;
static pcap_close_t p_pcap_close;
static pcap_dispatch_t p_pcap_dispatch;
static pcap_setnonblock_t p_pcap_setnonblock;
static pcap_findalldevs_t p_pcap_findalldevs;
static pcap_freealldevs_t p_pcap_freealldevs;
static pcap_sendpacket_t p_pcap_sendpacket;
static pcap_datalink_t p_pcap_datalink;
static pcap_lookupdev_t p_pcap_lookupdev;
static PacketCloseAdapter_t p_PacketCloseAdapter;
static PacketOpenAdapter_t p_PacketOpenAdapter;
static PacketSendPacket_t p_PacketSendPacket;
static PacketRequest_t p_PacketRequest;
static HINSTANCE pcap_library = NULL;
static HINSTANCE packet_library = NULL;
/* ------------------------------------------------------------------------- */
/* variables needed */
//static log_t rawnet_arch_log = LOG_ERR;
static pcap_if_t *EthernetPcapNextDev = NULL;
static pcap_if_t *EthernetPcapAlldevs = NULL;
static pcap_t *EthernetPcapFP = NULL;
static char *rawnet_device_name = NULL;
static char EthernetPcapErrbuf[PCAP_ERRBUF_SIZE];
#ifdef RAWNET_DEBUG_PKTDUMP
static void debug_output(const char *text, uint8_t *what, int count)
{
char buffer[256];
char *p = buffer;
char *pbuffer1 = what;
int len1 = count;
int i;
sprintf(buffer, "\n%s: length = %u\n", text, len1);
OutputDebugString(buffer);
do {
p = buffer;
for (i = 0; (i < 8) && len1 > 0; len1--, i++) {
sprintf( p, "%02x ", (unsigned int)(unsigned char)*pbuffer1++);
p += 3;
}
*(p - 1) = '\n';
*p = 0;
OutputDebugString(buffer);
} while (len1 > 0);
}
#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */
static void EthernetPcapFreeLibrary(void)
{
if (pcap_library) {
if (!FreeLibrary(pcap_library)) {
log_message(rawnet_arch_log, "FreeLibrary WPCAP.DLL failed!");
}
pcap_library = NULL;
if (packet_library) FreeLibrary(packet_library);
packet_library = NULL;
p_pcap_open_live = NULL;
p_pcap_close = NULL;
p_pcap_dispatch = NULL;
p_pcap_setnonblock = NULL;
p_pcap_findalldevs = NULL;
p_pcap_freealldevs = NULL;
p_pcap_sendpacket = NULL;
p_pcap_datalink = NULL;
p_pcap_lookupdev = NULL;
p_PacketOpenAdapter = NULL;
p_PacketCloseAdapter = NULL;
p_PacketSendPacket = NULL;
p_PacketRequest = NULL;
}
}
/* since I don't like typing too much... */
#define GET_PROC_ADDRESS_AND_TEST( _name_ ) \
p_##_name_ = (_name_##_t) GetProcAddress(x, #_name_); \
if (!p_##_name_ ) { \
log_message(rawnet_arch_log, "GetProcAddress " #_name_ " failed!"); \
EthernetPcapFreeLibrary(); \
return FALSE; \
}
static BOOL EthernetPcapLoadLibrary(void)
{
/*
* npcap is c:\System32\Npcap\wpcap.dll
* winpcap is c:\System32\wpcap.dll
*
*/
HINSTANCE x = NULL;
if (!pcap_library) {
/* This inserts c:\System32\Npcap\ into the search path. */
char buffer[512];
unsigned length;
length = GetSystemDirectory(buffer, sizeof(buffer) - sizeof("\\Npcap"));
if (length) {
strcat(buffer + length, "\\Npcap");
SetDllDirectory(buffer);
}
pcap_library = LoadLibrary(TEXT("wpcap.dll"));
if (!pcap_library) {
log_message(rawnet_arch_log, "LoadLibrary WPCAP.DLL failed!");
return FALSE;
}
x = pcap_library;
GET_PROC_ADDRESS_AND_TEST(pcap_open_live);
GET_PROC_ADDRESS_AND_TEST(pcap_close);
GET_PROC_ADDRESS_AND_TEST(pcap_dispatch);
GET_PROC_ADDRESS_AND_TEST(pcap_setnonblock);
GET_PROC_ADDRESS_AND_TEST(pcap_findalldevs);
GET_PROC_ADDRESS_AND_TEST(pcap_freealldevs);
GET_PROC_ADDRESS_AND_TEST(pcap_sendpacket);
GET_PROC_ADDRESS_AND_TEST(pcap_datalink);
GET_PROC_ADDRESS_AND_TEST(pcap_lookupdev);
}
if (!packet_library) {
packet_library = LoadLibrary(TEXT("Packet.dll"));
if (!packet_library) {
log_message(rawnet_arch_log, "LoadLibrary Packet.dll failed!");
return FALSE;
}
x = packet_library;
GET_PROC_ADDRESS_AND_TEST(PacketOpenAdapter);
GET_PROC_ADDRESS_AND_TEST(PacketCloseAdapter);
GET_PROC_ADDRESS_AND_TEST(PacketSendPacket);
GET_PROC_ADDRESS_AND_TEST(PacketRequest);
}
return TRUE;
}
#undef GET_PROC_ADDRESS_AND_TEST
/*
These functions let the UI enumerate the available interfaces.
First, rawnet_arch_enumadapter_open() is used to start enumeration.
rawnet_arch_enumadapter is then used to gather information for each adapter present
on the system, where:
ppname points to a pointer which will hold the name of the interface
ppdescription points to a pointer which will hold the description of the interface
For each of these parameters, new memory is allocated, so it has to be
freed with lib_free().
rawnet_arch_enumadapter_close() must be used to stop processing.
Each function returns 1 on success, and 0 on failure.
rawnet_arch_enumadapter() only fails if there is no more adpater; in this case,
*ppname and *ppdescription are not altered.
*/
int rawnet_arch_enumadapter_open(void)
{
if (!EthernetPcapLoadLibrary()) {
return 0;
}
if ((*p_pcap_findalldevs)(&EthernetPcapAlldevs, EthernetPcapErrbuf) == -1) {
log_message(rawnet_arch_log, "ERROR in rawnet_arch_enumadapter_open: pcap_findalldevs: '%s'", EthernetPcapErrbuf);
return 0;
}
if (!EthernetPcapAlldevs) {
log_message(rawnet_arch_log, "ERROR in rawnet_arch_enumadapter_open, finding all pcap devices - Do we have the necessary privilege rights?");
return 0;
}
EthernetPcapNextDev = EthernetPcapAlldevs;
return 1;
}
int rawnet_arch_enumadapter(char **ppname, char **ppdescription)
{
if (!EthernetPcapNextDev) {
return 0;
}
*ppname = lib_stralloc(EthernetPcapNextDev->name);
*ppdescription = lib_stralloc(EthernetPcapNextDev->description);
printf("%s: %s\n",
EthernetPcapNextDev->name ? EthernetPcapNextDev->name : "",
EthernetPcapNextDev->description ? EthernetPcapNextDev->description : ""
);
EthernetPcapNextDev = EthernetPcapNextDev->next;
return 1;
}
int rawnet_arch_enumadapter_close(void)
{
if (EthernetPcapAlldevs) {
(*p_pcap_freealldevs)(EthernetPcapAlldevs);
EthernetPcapAlldevs = NULL;
}
return 1;
}
static BOOL EthernetPcapOpenAdapter(const char *interface_name)
{
pcap_if_t *EthernetPcapDevice = NULL;
if (!rawnet_enumadapter_open()) {
return FALSE;
} else {
/* look if we can find the specified adapter */
char *pname;
char *pdescription;
BOOL found = FALSE;
if (interface_name) {
/* we have an interface name, try it */
EthernetPcapDevice = EthernetPcapAlldevs;
while (rawnet_enumadapter(&pname, &pdescription)) {
if (strcmp(pname, interface_name) == 0) {
found = TRUE;
}
lib_free(pname);
lib_free(pdescription);
if (found) break;
EthernetPcapDevice = EthernetPcapNextDev;
}
}
if (!found) {
/* just take the first adapter */
EthernetPcapDevice = EthernetPcapAlldevs;
}
}
EthernetPcapFP = (*p_pcap_open_live)(EthernetPcapDevice->name, 1700, 1, 20, EthernetPcapErrbuf);
if (EthernetPcapFP == NULL) {
log_message(rawnet_arch_log, "ERROR opening adapter: '%s'", EthernetPcapErrbuf);
rawnet_enumadapter_close();
return FALSE;
}
/* Check the link layer. We support only Ethernet for simplicity. */
if ((*p_pcap_datalink)(EthernetPcapFP) != DLT_EN10MB) {
log_message(rawnet_arch_log, "ERROR: Ethernet works only on Ethernet networks.");
rawnet_enumadapter_close();
(*p_pcap_close)(EthernetPcapFP);
EthernetPcapFP = NULL;
return FALSE;
}
if ((*p_pcap_setnonblock)(EthernetPcapFP, 1, EthernetPcapErrbuf) < 0) {
log_message(rawnet_arch_log, "WARNING: Setting PCAP to non-blocking failed: '%s'", EthernetPcapErrbuf);
}
rawnet_device_name = strdup(EthernetPcapDevice->name);
rawnet_enumadapter_close();
return TRUE;
}
/* ------------------------------------------------------------------------- */
/* the architecture-dependend functions */
int rawnet_arch_init(void)
{
//rawnet_arch_log = log_open("EthernetARCH");
if (!EthernetPcapLoadLibrary()) {
return 0;
}
return 1;
}
void rawnet_arch_pre_reset( void )
{
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log, "rawnet_arch_pre_reset().");
#endif
}
void rawnet_arch_post_reset( void )
{
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log, "rawnet_arch_post_reset().");
#endif
}
int rawnet_arch_activate(const char *interface_name)
{
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log, "rawnet_arch_activate().");
#endif
if (!EthernetPcapOpenAdapter(interface_name)) {
return 0;
}
return 1;
}
void rawnet_arch_deactivate( void )
{
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log, "rawnet_arch_deactivate().");
#endif
}
void rawnet_arch_set_mac( const uint8_t mac[6] )
{
#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES)
log_message(rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#endif
}
void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2])
{
#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES)
log_message(rawnet_arch_log, "New hash filter set: %08X:%08X.", hash_mask[1], hash_mask[0]);
#endif
}
/* int bBroadcast - broadcast */
/* int bIA - individual address (IA) */
/* int bMulticast - multicast if address passes the hash filter */
/* int bCorrect - accept correct frames */
/* int bPromiscuous - promiscuous mode */
/* int bIAHash - accept if IA passes the hash filter */
void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash)
{
#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES)
log_message(rawnet_arch_log, "rawnet_arch_recv_ctl() called with the following parameters:" );
log_message(rawnet_arch_log, "\tbBroadcast = %s", bBroadcast ? "TRUE" : "FALSE" );
log_message(rawnet_arch_log, "\tbIA = %s", bIA ? "TRUE" : "FALSE" );
log_message(rawnet_arch_log, "\tbMulticast = %s", bMulticast ? "TRUE" : "FALSE" );
log_message(rawnet_arch_log, "\tbCorrect = %s", bCorrect ? "TRUE" : "FALSE" );
log_message(rawnet_arch_log, "\tbPromiscuous = %s", bPromiscuous ? "TRUE" : "FALSE" );
log_message(rawnet_arch_log, "\tbIAHash = %s", bIAHash ? "TRUE" : "FALSE" );
#endif
}
void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver)
{
#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES)
log_message(rawnet_arch_log, "rawnet_arch_line_ctl() called with the following parameters:" );
log_message(rawnet_arch_log, "\tbEnableTransmitter = %s", bEnableTransmitter ? "TRUE" : "FALSE" );
log_message(rawnet_arch_log, "\tbEnableReceiver = %s", bEnableReceiver ? "TRUE" : "FALSE" );
#endif
}
typedef struct Ethernet_PCAP_internal_s {
unsigned int len;
uint8_t *buffer;
} Ethernet_PCAP_internal_t;
/* Callback function invoked by libpcap for every incoming packet */
static void EthernetPcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
Ethernet_PCAP_internal_t *pinternal = (void*)param;
/* determine the count of bytes which has been returned,
* but make sure not to overrun the buffer
*/
if (header->caplen < pinternal->len) {
pinternal->len = header->caplen;
}
memcpy(pinternal->buffer, pkt_data, pinternal->len);
}
/* the following function receives a frame.
If there's none, it returns a -1.
If there is one, it returns the length of the frame in bytes.
It copies the frame to *buffer and returns the number of copied
bytes as return value.
At most 'len' bytes are copied.
*/
static int rawnet_arch_receive_frame(Ethernet_PCAP_internal_t *pinternal)
{
int ret = -1;
/* check if there is something to receive */
if ((*p_pcap_dispatch)(EthernetPcapFP, 1, EthernetPcapPacketHandler, (void*)pinternal) != 0) {
/* Something has been received */
ret = pinternal->len;
}
#ifdef RAWNET_DEBUG_ARCH
log_message(rawnet_arch_log, "rawnet_arch_receive_frame() called, returns %d.", ret);
#endif
return ret;
}
int rawnet_arch_read(void *buffer, int nbyte) {
int len;
Ethernet_PCAP_internal_t internal;
internal.len = nbyte;
internal.buffer = (uint8_t *)buffer;
len = rawnet_arch_receive_frame(&internal);
if (len <= 0) return len;
#ifdef RAWNET_DEBUG_PKTDUMP
debug_output("Received frame: ", internal.buffer, internal.len);
#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */
return len;
}
int rawnet_arch_write(const void *buffer, int nbyte) {
#ifdef RAWNET_DEBUG_PKTDUMP
debug_output("Transmit frame: ", buffer, nbyte);
#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */
if ((*p_pcap_sendpacket)(EthernetPcapFP, (u_char *)buffer, nbyte) == -1) {
log_message(rawnet_arch_log, "WARNING! Could not send packet!");
return -1;
}
return nbyte;
}
char *rawnet_arch_get_standard_interface(void)
{
char *dev, errbuf[PCAP_ERRBUF_SIZE];
if (!EthernetPcapLoadLibrary()) {
return NULL;
}
dev = lib_stralloc((*p_pcap_lookupdev)(errbuf));
return dev;
}
extern int rawnet_arch_get_mtu(void) {
return -1;
}
extern int rawnet_arch_get_mac(uint8_t mac[6]) {
int rv = -1;
LPADAPTER outp = NULL;
char buffer[sizeof(PACKET_OID_DATA) + 6];
PPACKET_OID_DATA data = (PPACKET_OID_DATA)buffer;
if (!packet_library) return -1;
/* 802.5 = token ring, 802.3 = wired ethernet */
data->Oid = OID_802_3_CURRENT_ADDRESS; // OID_802_3_CURRENT_ADDRESS ? OID_802_3_PERMANENT_ADDRESS ?
data->Length = 6;
outp = p_PacketOpenAdapter(rawnet_device_name);
if (!outp || outp->hFile == INVALID_HANDLE_VALUE) return -1;
if (p_PacketRequest(outp, FALSE, data)) {
memcpy(mac, data->Data, 6);
rv = 0;
}
p_PacketCloseAdapter(outp);
return rv;
}
int rawnet_arch_status(void) {
return EthernetPcapFP ? 1 : 0;
}
#endif /* #ifdef HAVE_RAWNET */

372
src/rawnet/rawnetsupp.c Normal file
View File

@ -0,0 +1,372 @@
/*
* This file is a consolidation of functions required for tfe
* emulation taken from the following files
*
* lib.c - Library functions.
* util.c - Miscellaneous utility functions.
* crc32.c
*
* Written by
* Andreas Boose <viceteam@t-online.de>
* Ettore Perazzoli <ettore@comm2000.it>
* Andreas Matthies <andreas.matthies@gmx.net>
* Tibor Biczo <crown@mail.matav.hu>
* Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>*
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "rawnetsupp.h"
#define CRC32_POLY 0xedb88320
static unsigned long crc32_table[256];
static int crc32_is_initialized = 0;
void lib_free(void *ptr) {
free(ptr);
}
void *lib_malloc(size_t size) {
void *ptr = malloc(size);
if (ptr == NULL && size > 0) {
perror("lib_malloc");
exit(-1);
}
return ptr;
}
/*-----------------------------------------------------------------------*/
/* Malloc enough space for `str', copy `str' into it and return its
address. */
char *lib_stralloc(const char *str) {
char *ptr;
if (str == NULL) {
fprintf(stderr, "lib_stralloc\n");
exit(-1);
}
ptr = strdup(str);
if (!ptr) {
perror("lib_stralloc");
exit(-1);
}
return ptr;
}
/* Like realloc, but abort if not enough memory is available. */
void *lib_realloc(void *ptr, size_t size) {
void *new_ptr = realloc(ptr, size);
if (new_ptr == NULL) {
perror("lib_realloc");
exit(-1);
}
return new_ptr;
}
// Util Stuff
/* Set a new value to the dynamically allocated string *str.
Returns `-1' if nothing has to be done. */
int util_string_set(char **str, const char *new_value) {
if (*str == NULL) {
if (new_value != NULL)
*str = lib_stralloc(new_value);
} else {
if (new_value == NULL) {
lib_free(*str);
*str = NULL;
} else {
/* Skip copy if src and dest are already the same. */
if (strcmp(*str, new_value) == 0)
return -1;
*str = (char *)lib_realloc(*str, strlen(new_value) + 1);
strcpy(*str, new_value);
}
}
return 0;
}
// crc32 Stuff
unsigned long crc32_buf(const char *buffer, unsigned int len) {
int i, j;
unsigned long crc, c;
const char *p;
if (!crc32_is_initialized) {
for (i = 0; i < 256; i++) {
c = (unsigned long) i;
for (j = 0; j < 8; j++)
c = c & 1 ? CRC32_POLY ^ (c >> 1) : c >> 1;
crc32_table[i] = c;
}
crc32_is_initialized = 1;
}
crc = 0xffffffff;
for (p = buffer; len > 0; ++p, --len)
crc = (crc >> 8) ^ crc32_table[(crc ^ *p) & 0xff];
return ~crc;
}
void rawnet_hexdump(const void *what, int count) {
static const char hex[] = "0123456789abcdef";
char buffer1[16 * 3 + 1];
char buffer2[16 + 1];
unsigned offset;
unsigned char *cp = (unsigned char *)what;
offset = 0;
while (count > 0) {
unsigned char x = *cp++;
buffer1[offset * 3] = hex[x >> 4];
buffer1[offset * 3 + 1] = hex[x & 0x0f];
buffer1[offset * 3 + 2] = ' ';
buffer2[offset] = (x < 0x80) && isprint(x) ? x : '.';
--count;
++offset;
if (offset == 16 || count == 0) {
buffer1[offset * 3] = 0;
buffer2[offset] = 0;
fprintf(stderr, "%-50s %s\n", buffer1, buffer2);
offset = 0;
}
}
}
enum {
eth_dest = 0, // destination address
eth_src = 6, // source address
eth_type = 12, // packet type
eth_data = 14, // packet data
};
enum {
ip_ver_ihl = 0,
ip_tos = 1,
ip_len = 2,
ip_id = 4,
ip_frag = 6,
ip_ttl = 8,
ip_proto = 9,
ip_header_cksum = 10,
ip_src = 12,
ip_dest = 16,
ip_data = 20,
};
enum {
udp_source = 0, // source port
udp_dest = 2, // destination port
udp_len = 4, // length
udp_cksum = 6, // checksum
udp_data = 8, // total length udp header
};
enum {
bootp_op = 0, // operation
bootp_hw = 1, // hardware type
bootp_hlen = 2, // hardware len
bootp_hp = 3, // hops
bootp_transid = 4, // transaction id
bootp_secs = 8, // seconds since start
bootp_flags = 10, // flags
bootp_ipaddr = 12, // ip address knwon by client
bootp_ipclient = 16, // client ip from server
bootp_ipserver = 20, // server ip
bootp_ipgateway = 24, // gateway ip
bootp_client_hrd = 28, // client mac address
bootp_spare = 34,
bootp_host = 44,
bootp_fname = 108,
bootp_data = 236, // total length bootp packet
};
enum {
arp_hw = 14, // hw type (eth = 0001)
arp_proto = 16, // protocol (ip = 0800)
arp_hwlen = 18, // hw addr len (eth = 06)
arp_protolen = 19, // proto addr len (ip = 04)
arp_op = 20, // request = 0001, reply = 0002
arp_shw = 22, // sender hw addr
arp_sp = 28, // sender proto addr
arp_thw = 32, // target hw addr
arp_tp = 38, // target protoaddr
arp_data = 42, // total length of packet
};
enum {
dhcp_discover = 1,
dhcp_offer = 2,
dhcp_request = 3,
dhcp_decline = 4,
dhcp_pack = 5,
dhcp_nack = 6,
dhcp_release = 7,
dhcp_inform = 8,
};
static uint8_t oo[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t ff[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static int is_arp(const uint8_t *packet, unsigned size) {
return size == arp_data
&& packet[12] == 0x08 && packet[13] == 0x06 /* ARP */
&& packet[14] == 0x00 && packet[15] == 0x01 /* ethernet */
&& packet[16] == 0x08 && packet[17] == 0x00 /* ipv4 */
&& packet[18] == 0x06 /* hardware size */
&& packet[19] == 0x04 /* protocol size */
;
}
static int is_broadcast(const uint8_t *packet, unsigned size) {
return !memcmp(packet + 0, ff, 6);
}
static int is_unicast(const uint8_t *packet, unsigned size) {
return (*packet & 0x01) == 0;
}
static int is_multicast(const uint8_t *packet, unsigned size) {
return (*packet & 0x01) == 0x01 && !is_broadcast(packet, size);
}
static int is_dhcp_out(const uint8_t *packet, unsigned size) {
static uint8_t cookie[] = { 0x63, 0x82, 0x53, 0x63 };
return size >= 282
//&& !memcmp(&packet[0], ff, 6) /* broadcast */
&& packet[12] == 0x08 && packet[13] == 0x00
&& packet[14] == 0x45 /* version 4 */
&& packet[23] == 0x11 /* UDP */
//&& !memcmp(&packet[26], oo, 4) /* source ip */
//&& !memcmp(&packet[30], ff, 4) /* dest ip */
&& packet[34] == 0x00 && packet[35] == 0x44 /* source port */
&& packet[36] == 0x00 && packet[37] == 0x43 /* dest port */
//&& packet[44] == 0x01 /* dhcp boot req */
&& packet[43] == 0x01 /* ethernet */
&& packet[44] == 0x06 /* 6 byte mac */
&& !memcmp(&packet[278], cookie, 4)
;
}
static int is_dhcp_in(const uint8_t *packet, unsigned size) {
static uint8_t cookie[] = { 0x63, 0x82, 0x53, 0x63 };
return size >= 282
//&& !memcmp(&packet[0], ff, 6) /* broadcast */
&& packet[12] == 0x08 && packet[13] == 0x00
&& packet[14] == 0x45 /* version 4 */
&& packet[23] == 0x11 /* UDP */
//&& !memcmp(&packet[26], oo, 4) /* source ip */
//&& !memcmp(&packet[30], ff, 4) /* dest ip */
&& packet[34] == 0x00 && packet[35] == 0x43 /* source port */
&& packet[36] == 0x00 && packet[37] == 0x44 /* dest port */
//&& packet[44] == 0x01 /* dhcp boot req */
&& packet[43] == 0x01 /* ethernet */
&& packet[44] == 0x06 /* 6 byte mac */
&& !memcmp(&packet[278], cookie, 4)
;
}
static unsigned ip_checksum(const uint8_t *packet) {
unsigned x = 0;
unsigned i;
for (i = 0; i < ip_data; i += 2) {
if (i == ip_header_cksum) continue;
x += packet[eth_data + i + 0 ] << 8;
x += packet[eth_data + i + 1];
}
/* add the carry */
x += x >> 16;
x &= 0xffff;
return ~x & 0xffff;
}
void rawnet_fix_incoming_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]) {
if (memcmp(packet + 0, real_mac, 6) == 0)
memcpy(packet + 0, fake_mac, 6);
/* dhcp request - fix the hardware address */
if (is_unicast(packet, size) && is_dhcp_in(packet, size)) {
if (!memcmp(packet + 70, real_mac, 6))
memcpy(packet + 70, fake_mac, 6);
return;
}
}
void rawnet_fix_outgoing_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]) {
if (memcmp(packet + 6, fake_mac, 6) == 0)
memcpy(packet + 6, real_mac, 6);
if (is_arp(packet, size)) {
/* sender mac address */
if (!memcmp(packet + 22, fake_mac, 6))
memcpy(packet + 22, real_mac, 6);
return;
}
/* dhcp request - fix the hardware address */
if (is_broadcast(packet, size) && is_dhcp_out(packet, size)) {
if (!memcmp(packet + 70, fake_mac, 6))
memcpy(packet + 70, real_mac, 6);
return;
}
}

62
src/rawnet/rawnetsupp.h Normal file
View File

@ -0,0 +1,62 @@
/*
* This file is a consolidation of functions required for tfe
* emulation taken from the following files
*
* lib.h - Library functions.
* util.h - Miscellaneous utility functions.
* crc32.h
*
* Written by
* Andreas Boose <viceteam@t-online.de>
* Ettore Perazzoli <ettore@comm2000.it>
* Manfred Spraul <manfreds@colorfullife.com>
* Andreas Matthies <andreas.matthies@gmx.net>
* Tibor Biczo <crown@mail.matav.hu>
* Spiro Trikaliotis <Spiro.Trikaliotis@gmx.de>*
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _TFESUPP_H
#define _TFESUPP_H
#include <stdio.h>
#include <stdint.h>
extern FILE* g_fh; // Filehandle for log file
extern void *lib_malloc(size_t size);
extern void *lib_realloc(void *p, size_t size);
extern void lib_free(void *ptr);
extern char *lib_stralloc(const char *str);
extern int util_string_set(char **str, const char *new_value);
extern unsigned long crc32_buf(const char *buffer, unsigned int len);
extern void rawnet_hexdump(const void *what, int count);
extern void rawnet_fix_incoming_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]);
extern void rawnet_fix_outgoing_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]);
#define log_message(level,...) do { fprintf(stderr,__VA_ARGS__); fputs("\n", stderr); } while (0)
#endif

331
src/rawnet/vmnet_helper.c Normal file
View File

@ -0,0 +1,331 @@
/* vmnet helper */
/* because it needs root permissions ... sigh */
/*
* basicly... run as root, read messages from stdin, write to stdout.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <vmnet/vmnet.h>
#include <errno.h>
#include <err.h>
static interface_ref interface;
static uint8_t interface_mac[6];
static long interface_mtu;
static long interface_packet_size;
static vmnet_return_t interface_status;
static size_t buffer_size = 0;
static uint8_t *buffer = NULL;
enum {
MSG_QUIT,
MSG_STATUS,
MSG_READ,
MSG_WRITE
};
#define MAKE_MSG(msg, extra) (msg | ((extra) << 8))
ssize_t safe_read(void *buffer, size_t nbyte) {
ssize_t rv;
for(;;) {
rv = read(STDIN_FILENO, buffer, nbyte);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "read");
}
break;
}
return rv;
}
ssize_t safe_readv(const struct iovec *iov, int iovcnt) {
ssize_t rv;
for(;;) {
rv = readv(STDIN_FILENO, iov, iovcnt);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "readv");
}
break;
}
return rv;
}
ssize_t safe_write(const void *buffer, size_t nbyte) {
ssize_t rv;
for(;;) {
rv = write(STDOUT_FILENO, buffer, nbyte);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "write");
}
break;
}
return rv;
}
ssize_t safe_writev(const struct iovec *iov, int iovcnt) {
ssize_t rv;
for(;;) {
rv = writev(STDOUT_FILENO, iov, iovcnt);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "writev");
}
break;
}
return rv;
}
void msg_status(uint32_t size) {
struct iovec iov[4];
uint32_t msg = MAKE_MSG(MSG_STATUS, 6 + 4 + 4);
iov[0].iov_len = 4;
iov[0].iov_base = &msg;
iov[1].iov_len = 6;
iov[1].iov_base = interface_mac;
iov[2].iov_len = 4;
iov[2].iov_base = &interface_mtu;
iov[3].iov_len = 4;
iov[3].iov_base = &interface_packet_size;
safe_writev(iov, 4);
}
int classify_mac(uint8_t *mac) {
if ((mac[0] & 0x01) == 0) return 1; /* unicast */
if (memcmp(mac, "\xff\xff\xff\xff\xff\xff", 6) == 0) return 0xff; /* broadcast */
return 2; /* multicast */
}
void msg_read(uint32_t flags) {
/* flag to block broadcast, multicast, etc? */
int count = 1;
int xfer;
vmnet_return_t st;
struct vmpktdesc v;
struct iovec iov[2];
uint32_t msg;
for(;;) {
int type;
iov[0].iov_base = buffer;
iov[0].iov_len = interface_packet_size;
v.vm_pkt_size = interface_packet_size;
v.vm_pkt_iov = iov;
v.vm_pkt_iovcnt = 1;
v.vm_flags = 0;
count = 1;
st = vmnet_read(interface, &v, &count);
if (st != VMNET_SUCCESS) errx(1, "vmnet_read");
if (count < 1) break;
/* todo -- skip multicast messages based on flag? */
type = classify_mac(buffer);
if (type == 2) continue; /* multicast */
break;
}
xfer = count == 1 ? v.vm_pkt_size : 0;
msg = MAKE_MSG(MSG_READ, xfer);
iov[0].iov_len = 4;
iov[0].iov_base = &msg;
iov[1].iov_len = xfer;
iov[1].iov_base = buffer;
safe_writev(iov, count == 1 ? 2 : 1);
}
void msg_write(uint32_t size) {
ssize_t ok;
int count = 1;
vmnet_return_t st;
struct vmpktdesc v;
struct iovec iov;
uint32_t msg;
if (size > interface_packet_size) errx(1, "packet too big");
for(;;) {
ok = safe_read(buffer, size);
if (ok < 0) err(1,"read");
if (ok != size) errx(1,"message truncated");
break;
}
iov.iov_base = buffer;
iov.iov_len = size;
v.vm_pkt_size = size;
v.vm_pkt_iov = &iov;
v.vm_pkt_iovcnt = 1;
v.vm_flags = 0;
st = vmnet_write(interface, &v, &count);
if (st != VMNET_SUCCESS) errx(1, "vmnet_write");
msg = MAKE_MSG(MSG_WRITE, size);
iov.iov_len = 4;
iov.iov_base = &msg;
safe_writev(&iov, 1);
}
void startup(void) {
xpc_object_t dict;
dispatch_queue_t q;
dispatch_semaphore_t sem;
memset(interface_mac, 0, sizeof(interface_mac));
interface_status = 0;
interface_mtu = 0;
interface_packet_size = 0;
dict = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(dict, vmnet_operation_mode_key, VMNET_SHARED_MODE);
sem = dispatch_semaphore_create(0);
q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
interface = vmnet_start_interface(dict, q, ^(vmnet_return_t status, xpc_object_t params){
interface_status = status;
if (status == VMNET_SUCCESS) {
const char *cp;
cp = xpc_dictionary_get_string(params, vmnet_mac_address_key);
fprintf(stderr, "vmnet mac: %s\n", cp);
sscanf(cp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&interface_mac[0],
&interface_mac[1],
&interface_mac[2],
&interface_mac[3],
&interface_mac[4],
&interface_mac[5]
);
interface_mtu = xpc_dictionary_get_uint64(params, vmnet_mtu_key);
interface_packet_size = xpc_dictionary_get_uint64(params, vmnet_max_packet_size_key);
fprintf(stderr, "vmnet mtu: %u\n", (unsigned)interface_mtu);
fprintf(stderr, "vmnet packet size: %u\n", (unsigned)interface_packet_size);
}
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
if (interface_status == VMNET_SUCCESS) {
buffer_size = (interface_packet_size * 2 + 1023) & ~1023;
buffer = (uint8_t *)malloc(buffer_size);
} else {
if (interface) {
vmnet_stop_interface(interface, q, ^(vmnet_return_t status){
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
interface = NULL;
}
errx(1,"vmnet_start_interface failed");
}
dispatch_release(sem);
xpc_release(dict);
}
void shutdown(void) {
dispatch_queue_t q;
dispatch_semaphore_t sem;
if (interface) {
sem = dispatch_semaphore_create(0);
q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
vmnet_stop_interface(interface, q, ^(vmnet_return_t status){
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_release(sem);
interface = NULL;
interface_status = 0;
}
free(buffer);
buffer = NULL;
buffer_size = 0;
}
int main(int argc, char **argv) {
uint32_t msg;
uint32_t extra;
ssize_t ok;
startup();
for(;;) {
ok = safe_read(&msg, 4);
if (ok == 0) break;
if (ok != 4) errx(1,"read msg");
extra = msg >> 8;
msg = msg & 0xff;
switch(msg) {
case MSG_STATUS:
msg_status(extra);
break;
case MSG_QUIT:
shutdown();
exit(0);
case MSG_READ:
msg_read(extra);
break;
case MSG_WRITE:
msg_write(extra);
break;
}
}
shutdown();
exit(0);
}

265
src/readline.c Normal file
View File

@ -0,0 +1,265 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define HISTORY_SIZE 64
/* remove trailing whitespace and terminators */
static void cleanup_buffer(char *buffer, int size) {
while (size > 0) {
unsigned c = buffer[size-1];
if (c == ' ' || c == '\r' || c == '\n') {
--size;
continue;
}
break;
}
buffer[size] = 0;
}
#if defined(USE_LIBEDIT)
#include <histedit.h>
/* BSD libedit support */
EditLine *el = NULL;
History *hist = NULL;
HistEvent ev;
static const char *el_prompt = NULL;
static char *prompt_fn(EditLine *el) {
return el_prompt ? (char *)el_prompt : "";
}
char *x_readline(const char *prompt) {
static char buffer[1024];
int count = 0;
const char *cp;
if (!el) {
hist = history_init();
history(hist, &ev, H_SETSIZE, HISTORY_SIZE);
history(hist, &ev, H_SETUNIQUE, 1);
el = el_init("GS+", stdin, stdout, stderr);
el_set(el, EL_EDITOR, "emacs");
el_set(el, EL_BIND, "-e", NULL, NULL, NULL);
el_set(el, EL_HIST, history, hist);
el_set(el, EL_PROMPT, prompt_fn);
el_set(el, EL_SIGNAL, 1);
el_source(el, NULL);
}
el_prompt = prompt;
cp = el_gets(el, &count);
el_prompt = NULL;
if (count <= 0) {
if (prompt) fputc('\n', stdout);
return NULL;
}
if (count > sizeof(buffer) - 1) return "";
memcpy(buffer, cp, count);
cleanup_buffer(buffer, count);
if (*buffer)
history(hist, &ev, H_ENTER, buffer);
return buffer;
}
void x_readline_end(void) {
if (el) {
el_end(el);
el = NULL;
}
if (hist) {
history_end(hist);
hist = NULL;
}
}
#elif defined(USE_READLINE)
/* GNU Readline support */
#include <readline/readline.h>
#include <readline/history.h>
static int readline_init = 0;
/* suppress tab completion, which defaults to filenames */
static char **rl_acf(const char* text, int start, int end) {
return NULL;
}
char *x_readline(const char *prompt) {
static char buffer[1024];
char *cp;
int count;
if (!readline_init) {
rl_readline_name = "GS+";
rl_attempted_completion_function = rl_acf;
using_history();
stifle_history(HISTORY_SIZE);
readline_init = 1;
}
cp = readline(prompt);
if (!cp) {
if (prompt) fputc('\n', stdout);
return NULL;
}
count = strlen(cp);
if (count > sizeof(buffer) - 1) {
free(cp);
return "";
}
memcpy(buffer, cp, count);
cleanup_buffer(buffer, count);
free(cp);
/* append to history, but only if unique from prev. entry */
if (*buffer) {
HIST_ENTRY *h = history_get(history_length);
if (h == NULL || strcmp(buffer, h->line))
add_history(buffer);
}
return buffer;
}
void x_readline_end(void) {
}
#elif defined(_WIN32)
#include <windows.h>
static int readline_init = 0;
#ifndef HISTORY_NO_DUP_FLAG
#define HISTORY_NO_DUP_FLAG 0x01
#endif
char *x_readline(const char *prompt) {
static char buffer[1024];
DWORD count = 0;
BOOL ok;
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
/* MS CRT uses -2 to indicate there is no stdin/stdout/stderr fileno */
/*
if (h == INVALID_HANDLE_VALUE) {
//* cygwin? * /
fputs("GetStdHandle\n", stderr);
fflush(stderr);
return NULL;
char *cp;
fputs(prompt, stdout);
fflush(stdout);
return fgets(buffer, sizeof(buffer), stdin);
}
*/
if (!readline_init) {
//struct stat st;
CONSOLE_HISTORY_INFO chi;
DWORD mode;
memset(&chi, 0, sizeof(chi));
chi.cbSize = sizeof(CONSOLE_HISTORY_INFO);
chi.HistoryBufferSize = HISTORY_SIZE;
chi.NumberOfHistoryBuffers = 1; /* ???? */
chi.dwFlags = HISTORY_NO_DUP_FLAG;
ok = SetConsoleHistoryInfo(&chi);
if (!ok) {
fprintf(stderr, "SetConsoleHistoryInfo: %lx\n", GetLastError());
fflush(stderr);
}
mode = ENABLE_ECHO_INPUT | ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_QUICK_EDIT_MODE;
ok = SetConsoleMode(hIn, mode);
if (!ok) {
fprintf(stderr, "SetConsoleMode: %lx (h = %p)\n", GetLastError(), hIn);
fflush(stderr);
}
readline_init = 1;
}
fflush(stderr);
fflush(stdout);
ok = WriteConsole(hOut, prompt, strlen(prompt), NULL, NULL);
if (!ok) {
/* msys/cygwin? */
// fprintf(stderr, "WriteConsole: %lx (h = %p)\n", GetLastError(), hOut);
fflush(stderr);
if (prompt) fputs(prompt, stdout);
fflush(stdout);
char *cp = fgets(buffer, sizeof(buffer), stdin);
if (!cp) {
if (prompt) fputc('\n', stdout);
return NULL;
}
cleanup_buffer(buffer, strlen(buffer));
return buffer;
}
ok = ReadConsole(hIn, buffer, sizeof(buffer), &count, NULL);
if (!ok) {
if (prompt) fputc('\n', stdout);
// fflush(stdout);
// fprintf(stderr, "Error: %lx (h = %p)\n", GetLastError(), hIn);
// fprintf(stderr, "Type: %08x\n", GetFileType(hIn));
// fflush(stderr);
return NULL;
}
cleanup_buffer(buffer, count);
return buffer;
}
#else
#include <unistd.h>
char *x_readline(const char *prompt) {
static char buffer[1024];
if (prompt) fputs(prompt, stdout);
fflush(stdout);
for(;;) {
int ok = read(STDIN_FILENO, buffer, sizeof(buffer)-1);
if (ok < 0 && ok == EINTR) continue;
if (ok <= 0) {
if (prompt) fputc('\n', stdout);
return NULL;
}
cleanup_buffer(buffer, ok);
return buffer;
}
}
void x_readline_end(void) {
}
#endif

View File

@ -6,6 +6,7 @@
*/
#include "defc.h"
#include "scc.h"
#include "scc_llap.h"
#ifdef UNDER_CE
@ -25,7 +26,6 @@ extern int g_appletalk_turbo;
/* my scc port 0 == channel A = slot 1 = c039/c03b */
/* port 1 == channel B = slot 2 = c038/c03a */
#include "scc.h"
#define SCC_R14_DPLL_SOURCE_BRG 0x100
#define SCC_R14_FM_MODE 0x200

View File

@ -5,14 +5,13 @@
See LICENSE.txt for license (GPL v2)
*/
#include <ctype.h>
#ifdef _WIN32
# include <winsock2.h>
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
typedef int SOCKET;
#endif
#if defined(HPUX) || defined(__linux__) || defined(SOLARIS) || defined(MAC) || defined(__MACH__) || defined(_WIN32)
@ -28,10 +27,6 @@
#define SCC_MODEM_MAX_CMD_STR 128
#ifndef SOCKET
# define SOCKET word32 /* for non-windows */
#endif
STRUCT(Scc) {
int port;
int state /* 0 == disconnected, 1 == real serial port, 2 == socket, 3 == LocalTalk */;

View File

@ -8,8 +8,9 @@
/* This is an interface between the SCC emulation and the Virtual Imagewriter. */
#include "defc.h"
#include "scc.h"
#include "imagewriter.h"
#include "scc.h"
extern Scc scc_stat[2];
extern word32 g_vbl_count;

View File

@ -7,17 +7,16 @@
/* This file contains the Mac serial calls */
#ifdef MAC
#include "defc.h"
#include "scc.h"
#ifndef _WIN32
# include <termios.h>
#endif
#include <termios.h>
extern Scc scc_stat[2];
extern word32 g_c025_val;
#ifdef MAC
int scc_serial_mac_init(int port) {
char str_buf[1024];
Scc *scc_ptr;

View File

@ -11,20 +11,21 @@
#include "scc.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef UNDER_CE //OG
#include <signal.h>
#endif
#ifdef __CYGWIN__
#ifdef _WIN32
#include <Windows.h>
#define socklen_t int
#endif
extern Scc scc_stat[2];
extern int g_serial_modem[];
#if !(defined _MSC_VER || defined __CYGWIN__)
extern int h_errno;
#else
#define socklen_t int
#endif
int g_wsastartup_called = 0;
typedef unsigned short USHORT;
@ -108,19 +109,17 @@ void scc_socket_maybe_open_incoming(int port, double dcycs) {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("sockfd ret: %d\n", sockfd);
if(sockfd == -1) {
printf("socket ret: %d, errno: %d\n", sockfd, errno);
perror("socket");
scc_socket_close(port, 0, dcycs);
scc_ptr->socket_state = -1;
return;
}
/* printf("socket ret: %d\n", sockfd); */
on = 1;
ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on));
if(ret < 0) {
printf("setsockopt REUSEADDR ret: %d, err:%d\n",
ret, errno);
perror("setsockopt REUSEADDR");
scc_socket_close(port, 0, dcycs);
scc_ptr->socket_state = -1;
return;
@ -138,7 +137,7 @@ void scc_socket_maybe_open_incoming(int port, double dcycs) {
break;
}
/* else ret to bind was < 0 */
printf("bind ret: %d, errno: %d\n", ret, errno);
perror("bind");
inc++;
scc_socket_close_handle(sockfd);
printf("Trying next port: %d\n", 6501 + port + inc);
@ -180,7 +179,7 @@ void scc_socket_open_outgoing(int port, double dcycs) {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("sockfd ret: %d\n", sockfd);
if(sockfd == -1) {
printf("socket ret: %d, errno: %d\n", sockfd, errno);
perror("socket");
scc_socket_close(port, 1, dcycs);
return;
}
@ -190,8 +189,7 @@ void scc_socket_open_outgoing(int port, double dcycs) {
ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on));
if(ret < 0) {
printf("setsockopt REUSEADDR ret: %d, err:%d\n",
ret, errno);
perror("setsockopt REUSEADDR");
scc_socket_close(port, 1, dcycs);
return;
}
@ -218,9 +216,9 @@ void scc_socket_open_outgoing(int port, double dcycs) {
hostentptr = gethostbyname((const char*)&scc_ptr->modem_cmd_str[0]); // OG Added Cast
if(hostentptr == 0) {
#if defined(_WIN32)
fatal_printf("Lookup host %s failed\n", &scc_ptr->modem_cmd_str[0]);
fatal_printf("gethostbyname %s failed\n", &scc_ptr->modem_cmd_str[0]);
#else
fatal_printf("Lookup host %s failed, herrno: %d\n", &scc_ptr->modem_cmd_str[0], h_errno);
fatal_printf("gethostbyname %s failed: %s\n", &scc_ptr->modem_cmd_str[0], hstrerror(h_errno));
#endif
scc_socket_close_handle(sockfd);
scc_socket_close(port, 1, dcycs);
@ -234,7 +232,7 @@ void scc_socket_open_outgoing(int port, double dcycs) {
ret = connect(sockfd, (struct sockaddr *)&sa_in, sizeof(sa_in));
if(ret < 0) {
printf("connect ret: %d, errno: %d\n", ret, errno);
perror("connect");
scc_socket_close_handle(sockfd);
scc_socket_close(port, 1, dcycs);
return;
@ -276,14 +274,14 @@ void scc_socket_make_nonblock(int port, double dcycs) {
#else
flags = fcntl(sockfd, F_GETFL, 0);
if(flags == -1) {
printf("fcntl GETFL ret: %d, errno: %d\n", flags, errno);
perror("fcntl GETFL");
scc_socket_close(port, 1, dcycs);
scc_ptr->socket_state = -1;
return;
}
ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
if(ret == -1) {
printf("fcntl SETFL ret: %d, errno: %d\n", ret, errno);
perror("fcntl SETFL");
scc_socket_close(port, 1, dcycs);
scc_ptr->socket_state = -1;
return;
@ -374,12 +372,12 @@ void scc_accept_socket(int port, double dcycs) {
/* For Linux, we need to set O_NONBLOCK on the rdwrfd */
flags = fcntl(rdwrfd, F_GETFL, 0);
if(flags == -1) {
printf("fcntl GETFL ret: %d, errno: %d\n", flags,errno);
perror("fcntl GETFL");
return;
}
ret = fcntl(rdwrfd, F_SETFL, flags | O_NONBLOCK);
if(ret == -1) {
printf("fcntl SETFL ret: %d, errno: %d\n", ret, errno);
perror("fcntl SETFL");
return;
}
#endif

View File

@ -7,13 +7,13 @@
/* This file contains the Win32 COM1/COM2 calls */
#ifdef _WIN32
#include "defc.h"
#include "scc.h"
#ifdef __CYGWIN__
#include <Windows.h>
#include <NspAPI.h>
#endif
#ifdef UNDER_CE
#define vsnprintf _vsnprintf
@ -22,7 +22,6 @@
extern Scc scc_stat[2];
extern word32 g_c025_val;
#ifdef _WIN32
int scc_serial_win_init(int port) {
COMMTIMEOUTS commtimeouts;
TCHAR str_buf[8];

View File

@ -21,18 +21,31 @@ extern char g_config_gsplus_screenshot_dir[];
#define vsnprintf _vsnprintf
#endif
#ifdef HAVE_TFE
#include "tfe/tfesupp.h"
#include "tfe/protos_tfe.h"
#ifdef HAVE_RAWNET
#include "rawnet/rawnet.h"
#include "rawnet/cs8900.h"
#endif
#if defined (_WIN32) && !defined(WIN_SDL)|| defined(__CYGWIN__) && !defined(WIN_SDL)
#if defined(_WIN32) && !defined(HAVE_SDL)
#define WIN32_LEAN_AND_MEAN /* Tell windows we want less header gunk */
#define STRICT /* Tell Windows we want compile type checks */
#include <windows.h> /* Need a definition for LPTSTR in CYGWIN */
extern void get_cwd(LPTSTR buffer, int size);
#endif
#ifndef GSPLUS_DEBUGGER
int g_dbg_enable_port = 0;
void debug_server_poll(void) { }
int debug_events_waiting(void) { return 0; }
void debug_handle_event(void) { }
void debug_init(void) { }
void do_go_debug(void) { }
#endif
#define PC_LOG_LEN (8*1024)
int g_speed_fast; // OG Expose fast parameter
@ -69,7 +82,6 @@ const char *g_gsplus_default_paths[] = { // probably overkill on the paths
#define EV_VID_UPD 7
extern int g_stepping;
extern int g_dbg_step;
extern int g_c068_statereg;
@ -142,7 +154,8 @@ int g_iw2_emul = 0;
int g_serial_out_masking = 0;
int g_serial_modem[2] = { 0, 1 };
int g_ethernet = 0;
int g_ethernet_interface = 0;
char* g_ethernet_interface = "";
int g_ethernet_enabled = 0;
int g_parallel = 0;
int g_parallel_out_masking = 0;
int g_printer = 0;
@ -306,6 +319,7 @@ void sim65816_initglobals() {
g_mem_size_total = 256*1024; /* Total contiguous RAM from 0 */
}
#if 0
void show_pc_log() {
FILE *pcfile;
Pc_log *log_pc_ptr;
@ -399,7 +413,7 @@ void show_pc_log() {
fclose(pcfile);
}
#endif
#define TOOLBOX_LOG_LEN 64
@ -469,30 +483,6 @@ void show_toolbox_log() {
}
}
#if 0
/* get_memory_c is not used, get_memory_asm is, but this does what the */
/* assembly language would do */
word32 get_memory_c(word32 loc, int diff_cycles) {
byte *addr;
word32 result;
int index;
#ifdef CHECK_BREAKPOINTS
check_breakpoints_c(loc);
#endif
index = loc >> 8;
result = page_info[index].rd;
if(result & BANK_IO_BIT) {
return get_memory_io(loc, diff_cycles);
}
addr = (byte *)((result & 0xffffff00) + (loc & 0xff));
return *addr;
}
#endif
word32 get_memory_io(word32 loc, double *cyc_ptr) {
int tmp;
@ -541,71 +531,6 @@ word32 get_memory_io(word32 loc, double *cyc_ptr) {
return 0;
}
#if 0
word32 get_memory16_pieces(word32 loc, int diff_cycles) {
return(get_memory_c(loc, diff_cycles) +
(get_memory_c(loc+1, diff_cycles) << 8));
}
word32 get_memory24(word32 loc, int diff_cycles) {
return(get_memory_c(loc, diff_cycles) +
(get_memory_c(loc+1, diff_cycles) << 8) +
(get_memory_c(loc+2, diff_cycles) << 16));
}
#endif
#if 0
void set_memory(word32 loc, int val, int diff_cycles) {
byte *ptr;
word32 new_addr;
word32 tmp;
word32 or_val;
int or_pos;
int old_slow_val;
#ifdef CHECK_BREAKPOINTS
check_breakpoints_c(loc);
#endif
tmp = GET_PAGE_INFO_WR((loc>>8) & 0xffff);
if(tmp & BANK_IO) {
set_memory_io(loc, val, diff_cycles);
return;
}
if((loc & 0xfef000) == 0xe0c000) {
printf("set_memory_special: non-io for addr %08x, %02x, %d\n",
loc, val, diff_cycles);
halt_printf("tmp: %08x\n", tmp);
}
ptr = (byte *)(tmp & (~0xff));
new_addr = loc & 0xffff;
old_slow_val = val;
if(tmp & BANK_SHADOW) {
old_slow_val = g_slow_memory_ptr[new_addr];
} else if(tmp & BANK_SHADOW2) {
new_addr += 0x10000;
old_slow_val = g_slow_memory_ptr[new_addr];
}
if(old_slow_val != val) {
g_slow_memory_ptr[new_addr] = val;
or_pos = (new_addr >> SHIFT_PER_CHANGE) & 0x1f;
or_val = DEP1(1, or_pos, 0);
if((new_addr >> CHANGE_SHIFT) >= SLOW_MEM_CH_SIZE) {
printf("new_addr: %08x\n", new_addr);
exit(12);
}
slow_mem_changed[(new_addr & 0xffff) >> CHANGE_SHIFT] |= or_val;
}
ptr[loc & 0xff] = val;
}
#endif
void set_memory_io(word32 loc, int val, double *cyc_ptr) {
word32 tmp;
@ -653,25 +578,6 @@ void set_memory_io(word32 loc, int val, double *cyc_ptr) {
}
#if 0
void check_breakpoints_c(word32 loc) {
int index;
int count;
int i;
index = (loc & (MAX_BP_INDEX-1));
count = breakpoints[index].count;
if(count) {
for(i = 0; i < count; i++) {
if(loc == breakpoints[index].addrs[i]) {
halt_printf("Write hit breakpoint %d!\n", i);
}
}
}
}
#endif
void show_regs_act(Engine_reg *eptr) {
int tmp_acc, tmp_x, tmp_y, tmp_psw;
int kpc;
@ -760,7 +666,6 @@ void do_reset() {
engine.kpc = get_memory16_c(0x00fffc, 0);
g_stepping = 0;
g_dbg_step = 0;
if (g_irq_pending)
halt_printf("*** irq remainings...\n");
@ -797,6 +702,7 @@ void check_engine_asm_defines() {
CHECK(eptr, eptr->direct, ENGINE_REG_DIRECT, val1, val2);
CHECK(eptr, eptr->psr, ENGINE_REG_PSR, val1, val2);
CHECK(eptr, eptr->kpc, ENGINE_REG_KPC, val1, val2);
CHECK(eptr, eptr->flags, ENGINE_FLAGS, val1, val2);
pcptr = &pclog;
CHECK(pcptr, pcptr->dbank_kpc, LOG_PC_DBANK_KPC, val1, val2);
@ -884,8 +790,6 @@ void banner() {
int gsplusmain(int argc, char **argv) {
int diff;
int skip_amt;
int i;
char *final_arg = 0;
@ -944,31 +848,23 @@ int gsplusmain(int argc, char **argv) {
}
printer_init(g_printer_dpi,85,110,g_printer_output,g_printer_multipage != 0);
//If ethernet is enabled in config.gsport, let's initialize it
#ifdef HAVE_TFE
if (g_ethernet == 1)
#ifdef HAVE_RAWNET
g_ethernet_enabled = 0;
/* todo - pass device name via cmd line? */
if (g_ethernet)
{
int i = 0;
char *ppname = NULL;
char *ppdes = NULL;
if (tfe_enumadapter_open())
{
//Loop through the available adapters until we reach the interface number specified in config.gsport
while(tfe_enumadapter(&ppname,&ppdes))
{
if (i == g_ethernet_interface) break;
i++;
}
tfe_enumadapter_close();
printf("Using host ethernet interface: %s\nUthernet support is ON.\n",ppdes);
if (!g_ethernet_interface || !*g_ethernet_interface) {
g_ethernet_interface = rawnet_get_standard_interface();
}
else
{
printf("No ethernet host adapters found. Do you have PCap installed/enabled?\nUthernet support is OFF.\n");
if (g_ethernet_interface && *g_ethernet_interface) {
if (cs8900_init() >= 0 && cs8900_activate(g_ethernet_interface) >= 0) {
g_ethernet_enabled = 1;
} else {
glogf("Unable to start ethernet (%s).\n", g_ethernet_interface);
}
}
set_tfe_interface(ppname); //Connect the emulated ethernet device with the selected host adapter
lib_free(ppname);
lib_free(ppdes);
tfe_init();
}
#endif
@ -992,7 +888,6 @@ int gsplusmain(int argc, char **argv) {
do_reset();
g_stepping = 0;
g_dbg_step = 0;
// OG Notify emulator has been initialized and ready to accept external events
g_initialized = 1;
@ -1003,8 +898,6 @@ int gsplusmain(int argc, char **argv) {
do_go_debug();
} else {
do_go();
/* If we get here, we hit a breakpoint, call debug intfc */
do_debug_intfc();
}
// OG Notify emulator is being closed, and cannot accept events anymore
@ -1020,6 +913,13 @@ int gsplusmain(int argc, char **argv) {
load_roms_shut_memory();
clear_fatal_logs();
#if HAVE_RAWNET
if (g_ethernet_enabled) {
cs8900_deactivate();
cs8900_shutdown();
}
#endif
// OG Not needed anymore : the emulator will quit gently
//my_exit(0);
end_screen();
@ -1095,7 +995,7 @@ void gsport_expand_path(char *out_ptr, const char *in_ptr, int maxlen) {
if(!strncmp("0", name_buf, 128)) {
/* Replace ${0} with g_argv0_path */
tmp_ptr = &(g_argv0_path[0]);
#if defined (_WIN32) && !defined(WIN_SDL)|| defined(__CYGWIN__) && !defined(WIN_SDL)
#if defined(_WIN32) && !defined(HAVE_SDL)
} else if(!strncmp("PWD", name_buf, 128)) {
/* Replace ${PWD} with cwd in Windows */
get_cwd(out_ptr,128);
@ -1464,7 +1364,7 @@ void setup_zip_speeds() {
}
}
void run_prog() {
int run_prog() {
Fplus *fplus_ptr;
Event *this_event;
Event *db1;
@ -1576,7 +1476,7 @@ void run_prog() {
engine.fcycles = prerun_fcycles;
fcycles_stop = (g_event_start.next->dcycs - g_last_vbl_dcycs) +
0.001;
if(g_stepping || g_dbg_step < 0) {
if(g_stepping || engine.flags) {
fcycles_stop = prerun_fcycles;
}
g_fcycles_stop = fcycles_stop;
@ -1612,13 +1512,14 @@ void run_prog() {
if(ret != 0) {
g_engine_action++;
handle_action(ret);
ret >>= 28;
}
if(halt_sim == HALT_EVENT) {
if(halt_sim & HALT_EVENT) {
g_engine_halt_event++;
/* if we needed to stop to check for interrupts, */
/* clear halt */
halt_sim = 0;
halt_sim &= ~HALT_EVENT;
}
#if 0
@ -1635,10 +1536,10 @@ void run_prog() {
this_event = g_event_start.next;
while(dcycs >= this_event->dcycs) {
if(halt_sim != 0 && halt_sim != HALT_EVENT) {
if(halt_sim & ~HALT_EVENT) {
break;
}
if(g_stepping || g_dbg_step != 0) {
if(g_stepping) {
printf("HIT STEPPING BREAK!\n");
break;
}
@ -1705,19 +1606,36 @@ void run_prog() {
}
#endif
if(halt_sim != 0 && halt_sim != HALT_EVENT) {
if (ret == RET_MP) break;
if (ret == RET_BP) break;
if (ret == RET_BRK) break;
if (ret == RET_COP) break;
engine.flags &= ~(FLAG_IGNORE_BP | FLAG_IGNORE_MP | FLAG_IGNORE_BRK);
if(g_stepping) {
ret = 0;
break;
}
if(g_stepping || g_dbg_step != 0) {
if (halt_sim & ~HALT_EVENT) {
if(halt_sim & 0x07) {
/* halt_printf() */
halt_sim &= ~0x07;
ret = RET_HALT;
}
break;
}
}
#if 0
if(!g_testing) {
printf("leaving run_prog, halt_sim:%d\n", halt_sim);
}
#endif
x_auto_repeat_on(0);
return ret;
}
void add_irq(word32 irq_mask) {
@ -2321,6 +2239,7 @@ void init_reg() {
engine.direct = 0;
engine.psr = 0x134;
engine.fplus_ptr = 0;
engine.flags = 0;
}
@ -2330,9 +2249,6 @@ void handle_action(word32 ret) {
type = EXTRU(ret,3,4);
switch(type) {
case RET_BREAK:
do_break(ret & 0xff);
break;
case RET_COP:
do_cop(ret & 0xff);
break;
@ -2350,14 +2266,6 @@ void handle_action(word32 ret) {
case RET_C70D:
do_c70d(ret);
break;
#if 0
case RET_ADD_DEC_8:
do_add_dec_8(ret);
break;
case RET_ADD_DEC_16:
do_add_dec_16(ret);
break;
#endif
case RET_IRQ:
irq_printf("Special fast IRQ response. irq_pending: %x\n",
g_irq_pending);
@ -2368,6 +2276,12 @@ void handle_action(word32 ret) {
case RET_STP:
do_stp();
break;
case RET_BP:
case RET_MP:
case RET_BRK:
case RET_HALT:
/* handled elsewhere */
break;
default:
halt_printf("Unknown special action: %08x!\n", ret);
}

View File

@ -32,8 +32,7 @@ int g_queued_nonsamps = 0;
int g_num_osc_interrupting = 0;
int g_sound_play_depth = 0;
/* Workaround - gcc in cygwin wasn't defining _WIN32, substituted WIN_SOUND instead */
#if defined(HPUX) || defined(__linux__) || defined(WIN_SOUND) || defined(MAC) || defined(HAVE_SDL)
#if defined(HPUX) || defined(__linux__) || defined(_WIN32) || defined(MAC) || defined(HAVE_SDL)
int g_audio_enable = -1;
#else
# if defined(OSS)
@ -243,8 +242,7 @@ void sound_init() {
void sound_init_general() {
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(HAVE_SDL)
#if !defined(_WIN32) && !defined(MAC) && !defined(HAVE_SDL)
int pid;
int shmid;
int tmp;
@ -255,8 +253,7 @@ void sound_init_general() {
int size;
int ret;
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(HAVE_SDL)
#if !defined(_WIN32) && !defined(MAC) && !defined(HAVE_SDL)
if(!g_use_shmem) {
if(g_audio_enable < 0) {
printf("Defaulting audio off for slow X display\n");
@ -273,8 +270,7 @@ void sound_init_general() {
}
size = SOUND_SHM_SAMP_SIZE * SAMPLE_CHAN_SIZE;
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(HAVE_SDL)
#if !defined(_WIN32) && !defined(MAC) && !defined(HAVE_SDL)
shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777);
if(shmid < 0) {
printf("sound_init: shmget ret: %d, errno: %d\n", shmid, errno);
@ -303,8 +299,8 @@ void sound_init_general() {
g_sound_shm_addr = shmaddr;
fflush(stdout);
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(MAC) && !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(HAVE_SDL)
#if !defined(MAC) && !defined(_WIN32) && !defined(HAVE_SDL)
/* prepare pipe so parent can signal child each other */
/* pipe[0] = read side, pipe[1] = write end */
ret = pipe(&g_pipe_fd[0]);
@ -356,9 +352,9 @@ void sound_init_general() {
#else
# if defined (HAVE_SDL)
sdlsnd_init(shmaddr);
# elif defined (WIN_SOUND)
# elif defined (_WIN32)
win32snd_init(shmaddr);
# elif defined (MAC) && !defined(HAVE_SDL)
# elif defined (MAC)
macsnd_init(shmaddr);
# endif
#endif
@ -419,13 +415,14 @@ void sound_shutdown() {
// OG stop sound and free memory on sound_shutdown
sound_reset(g_cur_dcycs);
#ifdef WIN_SOUND /* Workaround - gcc in cygwin wasn't defining _WIN32 */
win32snd_shutdown();
#elif defined(HAVE_SDL)
#if defined(HAVE_SDL)
if((g_audio_enable != 0)) {
//sdlsnd_shutdown();
sound_shutdown_sdl();
}
#elif defined(_WIN32)
win32snd_shutdown();
#else
if((g_audio_enable != 0) && g_pipe_fd[1] != 0) {
close(g_pipe_fd[1]);
@ -607,11 +604,11 @@ void send_sound(int real_samps, int size) {
}
DOC_LOG("send_sound", -1, g_last_sound_play_dsamp,
(real_samps << 30) + size);
// Workaround - gcc in cygwin wasn't defining _WIN32
#if defined(WIN_SOUND) || defined(MAC) && !defined(HAVE_SDL)
child_sound_playit(tmp);
#elif defined(HAVE_SDL)
#if defined(HAVE_SDL)
sound_write_sdl( real_samps, size);
#elif defined(_WIN32) || defined(MAC)
child_sound_playit(tmp);
#else
/* Although this looks like a big/little-endian issue, since the */
/* child is also reading an int, it just works with no byte swap */

View File

@ -21,7 +21,7 @@ long sound_init_device_sdl();
# include <sys/soundcard.h>
#endif
#ifndef WIN_SOUND /* Workaround - gcc in cygwin wasn't defining _WIN32 */
#ifndef _WIN32
# include <sys/socket.h>
# include <netinet/in.h>
#endif
@ -77,9 +77,9 @@ void reliable_buf_write(word32 *shm_addr, int pos, int size) {
#if defined(HAVE_SDL)
//ret = sdl_send_audio(ptr, size);
#elif defined(WIN_SOUND)
#elif defined(_WIN32)
ret = win32_send_audio(ptr, size);
#elif defined(MAC) && !defined(HAVE_SDL)
#elif defined(MAC)
ret = mac_send_audio(ptr, size);
#else
ret = write(g_audio_socket, ptr, size);
@ -129,10 +129,10 @@ void child_sound_loop(int read_fd, int write_fd, word32 *shm_addr) {
child_sound_init_linux();
#elif HPUX
child_sound_init_hpdev();
#elif WIN_SOUND
#elif defined(_WIN32)
child_sound_init_win32();
return;
#elif defined(MAC) && !defined(HAVE_SDL)
#elif defined(MAC)
child_sound_init_mac();
return;
#endif

View File

@ -4,3 +4,7 @@ add_library(tfe tfe.c tfearch.c tfesupp.c)
target_compile_definitions(tfe PUBLIC HAVE_TFE)
if(WIN32)
target_include_directories(tfe PRIVATE ../rawnet/include)
target_link_libraries(tfe ws2_32) # winsock2
endif()

View File

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E810477A-E004-4308-A58A-21393213EF89}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>tfe</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;TFE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<BufferSecurityCheck>false</BufferSecurityCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<CompileAs>CompileAsC</CompileAs>
<FunctionLevelLinking>true</FunctionLevelLinking>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;TFE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<CompileAs>CompileAsC</CompileAs>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\arch\win32\bittypes.h" />
<ClInclude Include="..\arch\win32\bpf.h" />
<ClInclude Include="..\arch\win32\dirent-win32.h" />
<ClInclude Include="..\arch\win32\ip6_misc.h" />
<ClInclude Include="..\arch\win32\pcap-stdinc.h" />
<ClInclude Include="..\arch\win32\pcap.h" />
<ClInclude Include="tfesupp.h" />
<ClInclude Include="types.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="tfe.c" />
<ClCompile Include="tfearch.c" />
<ClCompile Include="tfesupp.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,54 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="tfesupp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\arch\win32\bittypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\arch\win32\bpf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\arch\win32\dirent-win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\arch\win32\ip6_misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\arch\win32\pcap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\arch\win32\pcap-stdinc.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="tfe.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tfesupp.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tfearch.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

Some files were not shown because too many files have changed in this diff Show More