/*
BPFILTER.h
Copyright (C) 2012 Michael Fort, Paul C. Pratt
You can redistribute this file and/or modify it under the terms
of version 2 of the GNU General Public License as published by
the Free Software Foundation. You should have received a copy
of the license along with this file; see the file COPYING.
This file 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
license for more details.
*//*
Berkeley Packet Filter for localtalk emulation
*//* BPF and devices */staticunsignedchardevice_address[6]={0};staticunsignedintdevice_buffer_size=0;staticintfd=-1;/* BPF file descriptor */staticstructbpf_versionbpf_version;staticstructbpf_programbpf_program;staticstructbpf_insninsns[]={/* Program for BPF to filter out non-LTOE packets */BPF_STMT(BPF_LD+BPF_H+BPF_ABS,12),BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K,0x809B,0,1),BPF_STMT(BPF_RET+BPF_K,65535),BPF_STMT(BPF_RET+BPF_K,0),};GLOBALVARui3pLT_TxBuffer=NULL;/* Transmit state */GLOBALVARui4rLT_TxBuffSz=0;/*
Transmit buffer that is reused from tx packet to tx packet.
The 's' byte represents the source mac address (ours) and we don't
have to initialize it because the MAC device will automatically
fill it in for us. The four 'p' bytes represent the process number
of this Mini vMac application. It helps differentiate packets
between two applications running on the same machine. It is not
used at this time. There is a small chance two applications could
get the same LLAP/SDLC address to start with and would not work
correctly (1 in 254). The 'S' bytes are the size of the LLAP packet
since it can be smaller than the minimum sized Ethernet frame.
The process number is replaced at initialization. The size is
updated just before sending to BPF. All LLAP data is inserted
starting at byte 20.
*/staticunsignedchartx_buffer[20+LT_TxBfMxSz]="\xFF\xFF\xFF\xFF\xFF\xFFssssss\x80\x9BppppSS";/* Receive state */GLOBALVARui3pLT_RxBuffer=NULL;/* When data pending, this is used */GLOBALVARui5rLT_RxBuffSz=0;/* When data pending, this is used *//* Macro used by only the get_sockaddrs function for readability. */#define ROUNDUP(a, size) \ (((a) & ((size) - 1)) ? (1 + ((a) | ((size) - 1))) : (a))/*
Utility function needed for walking the addresses of the
kernel route lookup
*/LOCALPROCget_sockaddrs(intaddrs,structsockaddr*sa,structsockaddr**rti_info){intloop;intincr;for(loop=0;loop<RTAX_MAX;loop++){if(addrs&(1<<loop)){rti_info[loop]=sa;incr=sa->sa_len?ROUNDUP(sa->sa_len,sizeof(uint32_t)):sizeof(uint32_t);sa=(structsockaddr*)((unsignedlongint)sa+incr);}else{rti_info[loop]=NULL;}}}/*
This ugly function does a lot of steps to prepare the BPF
for our use.
1. Find the ethernet interface that the default route uses.
2. Determine the maximum number of BPF devices can exist.
3. Search for a usable BPF device and open it.
4. Set the BPF device to use our ethernet interface.
5. Get the proper buffer size to use with the BPF device.
6. Set some useful modes of operation on the BPF device.
7. Install a program on the device that filters out non-LTOE
packets.
*/LOCALFUNCintget_ethernet(void){intresult;intsize;structrt_msghdr*message;structsockaddr_in*addrs;structsockaddr*sa_list[RTAX_MAX];intloop;charfilename[64];structifreqifreq;intenable=1;structkinfo_prockp;size_tlen=sizeof(kp);intmax=4;chardevice[32];/* Get a socket to routed for IPv4 */fd=socket(PF_ROUTE,SOCK_RAW,AF_INET);if(fd==-1){returnfalseblnr;}/* Allocate a message */size=sizeof(structrt_msghdr)+16*sizeof(structsockaddr_in);message=(structrt_msghdr*)malloc(size);if(!message){close(fd);returnfalseblnr;}memset(message,0,size);addrs=(structsockaddr_in*)(message+1);/* Fill in the re