http://wiki.ucis.nl/index.php?title=Projects/Software/TunTapIO/rawsock.c&feed=atom&action=history
Projects/Software/TunTapIO/rawsock.c - Revision history
2024-03-29T05:54:29Z
Revision history for this page on the wiki
MediaWiki 1.38.4
http://wiki.ucis.nl/index.php?title=Projects/Software/TunTapIO/rawsock.c&diff=154&oldid=prev
Admin: 1 revision imported
2022-11-09T14:49:54Z
<p>1 revision imported</p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<tr class="diff-title" lang="en">
<td colspan="1" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="1" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 15:49, 9 November 2022</td>
</tr><tr><td colspan="2" class="diff-notice" lang="en"><div class="mw-diff-empty">(No difference)</div>
</td></tr></table>
Admin
http://wiki.ucis.nl/index.php?title=Projects/Software/TunTapIO/rawsock.c&diff=153&oldid=prev
Admin: Nieuwe pagina aangemaakt met '<pre> /********************************************************************** * rsio - raw socket to stdin/out proxy * * Written by: Ivo...'
2009-04-22T23:32:03Z
<p>Nieuwe pagina aangemaakt met '<pre> /********************************************************************** * rsio - raw socket to stdin/out proxy * * Written by: Ivo...'</p>
<p><b>New page</b></p><div><pre><br />
/**********************************************************************<br />
* rsio - raw socket to stdin/out proxy *<br />
* Written by: Ivo Smits <Ivo@UFO-Net.nl> *<br />
* *<br />
* Compile using: gcc rawsock.c -o rsio *<br />
* *<br />
* Many thanks to: *<br />
* - http://www.blug.linux.no/rfc1149/ *<br />
* - http://linux.about.com/od/commands/l/blcmdl2_select.htm *<br />
* - http://bochs.sourceforge.net/ (the iodev/eth_linux.cc module) *<br />
* *<br />
**********************************************************************/<br />
<br />
#include <stdio.h><br />
#include <stdlib.h><br />
#include <string.h><br />
#include <fcntl.h><br />
#ifndef HAVE_NETINET_IN_H<br />
#include <netinet/in.h><br />
#endif<br />
<br />
#include <sys/ioctl.h><br />
<br />
#include <errno.h><br />
#include <dirent.h><br />
<br />
#include <errno.h><br />
#include <sys/types.h><br />
#include <sys/socket.h><br />
#include <netpacket/packet.h><br />
#include <netinet/in.h><br />
#include <net/ethernet.h><br />
#include <net/if.h><br />
#include <linux/types.h><br />
#include <linux/filter.h><br />
#include <linux/if_ether.h><br />
<br />
// The main program, this is where all the magic happens<br />
int main(int argc, char** argv) {<br />
int DumpStats = 1;<br />
int IncludePLen = 1;<br />
<br />
//Parse command line arguments<br />
if (argc > 1) {<br />
if (strcmp(argv[1], "-h") == 0) {<br />
fprintf(stderr, "rsio - raw socket to stdio proxy\n");<br />
fprintf(stderr, "Usage: %s INTF [-raw|-ip] [CLEN] [-prom]\n", argv[0]);<br />
fprintf(stderr, " INTF: the name of the network interface to connect to\n");<br />
fprintf(stderr, " -raw: raw ethernet communication (default)\n");<br />
fprintf(stderr, " -tun: IP level communication\n");<br />
fprintf(stderr, " CLEN: capture size (should be the same as the mtu, default: %d)\n", ETH_FRAME_LEN);<br />
fprintf(stderr, " -prom: enable promiscious mode (warning, won't be disabled)\n");<br />
fprintf(stderr, "Note that the arguments should be in exactly THIS order.\n");<br />
fprintf(stderr, "Report bugs to <Ivo@UFO-Net.nl>\n");<br />
exit(0);<br />
}<br />
} else {<br />
//Application won't run without arguments<br />
fprintf(stderr, "Try: %s -h\n", argv[0]);<br />
exit(1);<br />
}<br />
<br />
int sock; //The socket<br />
<br />
int CaptureLen = ETH_FRAME_LEN;<br />
{<br />
int linktype = 0; //Default to ethernet packets (0=ethernet, 1=IP)<br />
if (argc > 2 && strcmp(argv[2], "-ip") == 0) linktype = 1;<br />
<br />
if (linktype == 1) CaptureLen = ETH_DATA_LEN;<br />
<br />
//Different capture length?<br />
if (argc > 3) CaptureLen = atoi(argv[3]);<br />
if (CaptureLen < 1) {<br />
fprintf(stderr, "Capture length %d invalid!\n", CaptureLen);<br />
exit(1);<br />
}<br />
fprintf(stderr, "Max packet length: %d\n", CaptureLen);<br />
<br />
//Open the socket!<br />
int socktype, sockproto;<br />
#warning "ToDo: add some more protocols from /usr/include/linux/if_ether.h!"<br />
if (linktype == 1) {<br />
fprintf(stderr, "Warning: IP mode does not catch sent packets!\n");<br />
#warning "IP mode does not catch sent packets!"<br />
socktype = SOCK_DGRAM;<br />
sockproto = htons(ETH_P_IP);<br />
} else {<br />
socktype = SOCK_RAW;<br />
sockproto = htons(ETH_P_ALL);<br />
}<br />
if ((sock = socket(PF_PACKET, socktype, sockproto)) == -1) {<br />
fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));<br />
exit(1);<br />
}<br />
}<br />
<br />
//Bind to given interface by name<br />
{<br />
const char *dev; //Device to connect to<br />
strcpy(dev, argv[1]);<br />
<br />
//Translate interface name to index<br />
struct ifreq ifr;<br />
memset(&ifr, 0, sizeof(ifr));<br />
strcpy(ifr.ifr_name, dev);<br />
if (ioctl(sock, SIOCGIFINDEX, &ifr) == -1) {<br />
fprintf(stderr, "Failed to get index for interface: '%s'\n", dev);<br />
close(sock);<br />
exit(1);<br />
}<br />
<br />
// Bind to given interface<br />
struct sockaddr_ll sll;<br />
memset(&sll, 0, sizeof(sll));<br />
sll.sll_family = AF_PACKET;<br />
sll.sll_ifindex = ifr.ifr_ifindex;<br />
if (bind(sock, (struct sockaddr *)&sll, (socklen_t)sizeof(sll)) == -1) {<br />
fprintf(stderr, "Could not bind to interface '%s': %s\n", dev, strerror(errno));<br />
close(sock);<br />
exit(1);<br />
}<br />
<br />
#warning "Disable promiscious mode on exit! (signal handler?)"<br />
if (argc > 5 && strcmp(argv[5], "-prom") == 0) {<br />
register int Ret;<br />
if (Ret = ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {<br />
fprintf(stderr, "Failed to get interface flags: '%s'\n", Ret);<br />
close(sock);<br />
exit(1);<br />
}<br />
ifr.ifr_flags |= IFF_PROMISC;<br />
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {<br />
fprintf(stderr, "Failed to set interface flags for promisc mode: '%s'\n", Ret);<br />
close(sock);<br />
exit(1);<br />
}<br />
fprintf(stderr, "Promiscious mode enabled!\n");<br />
}<br />
}<br />
<br />
fprintf(stderr, "Proxy ready for action!\n");<br />
<br />
fd_set fdsRead, fdsWrite; //FileDescriptor sets for select()<br />
unsigned char RBuf[CaptureLen], WBuf[CaptureLen]; //Data buffers<br />
int RBufLen = 0, WBufLen = 0; //Packet length<br />
int PLen;<br />
<br />
//Start an infinite loop<br />
while (1) {<br />
if (WBufLen < 0 || RBufLen < 0) {<br />
fprintf(stderr, "WBufLen < 0 or RBufLen < 0 :|\n");<br />
exit(2);<br />
}<br />
<br />
FD_ZERO(&fdsRead); //Clear FD set<br />
if (RBufLen == 0) FD_SET(sock, &fdsRead); //Add socket<br />
if (WBufLen == 0) FD_SET(0, &fdsRead); //Add stdin<br />
<br />
FD_ZERO(&fdsWrite); //Clear FD set<br />
if (WBufLen > 0) FD_SET(sock, &fdsWrite); //Add socket<br />
if (RBufLen > 0) FD_SET(1, &fdsWrite); //Add stdout<br />
<br />
if (select(sock + 1, &fdsRead, &fdsWrite, NULL, NULL) < 0) {<br />
if (errno == EAGAIN || errno == EINTR) {<br />
continue; //Retry select<br />
} else {<br />
fprintf(stderr, "An unhandled error occured in select: %d", errno);<br />
exit(5);<br />
}<br />
}<br />
<br />
//Read from socket<br />
if (FD_ISSET(sock, &fdsRead) && RBufLen == 0) {<br />
RBufLen = read(sock, RBuf, CaptureLen);<br />
if (RBufLen == 0) {<br />
fprintf(stderr, "End of file on socket\n");<br />
exit(0);<br />
} else if (RBufLen < 0) {<br />
fprintf(stderr, "Some error occured while reading from socket: %d\n", RBufLen);<br />
exit(4);<br />
}<br />
if (DumpStats != 0) fprintf(stderr, "R: %d\n", RBufLen);<br />
}<br />
//Write to socket<br />
if (FD_ISSET(sock, &fdsWrite) && WBufLen > 0) {<br />
write(sock, WBuf, WBufLen);<br />
if (DumpStats != 0) fprintf(stderr, "W: %d\n", WBufLen);<br />
WBufLen = 0;<br />
}<br />
<br />
//Read from stdin (FD 0)<br />
if (FD_ISSET(0, &fdsRead) && WBufLen == 0) {<br />
if (IncludePLen == 1) {<br />
WBufLen = read(0, &PLen, 4);<br />
}<br />
if (IncludePLen == 0 || PLen > CaptureLen) {<br />
PLen = CaptureLen;<br />
}<br />
if (IncludePLen == 0 || WBufLen > 0) {<br />
WBufLen = read(0, WBuf, PLen);<br />
}<br />
if (WBufLen == 0) {<br />
fprintf(stderr, "End of file on stdin\n");<br />
exit(0);<br />
} else if (WBufLen < 0) {<br />
fprintf(stderr, "Some error occured while reading stdin: %d\n", WBufLen);<br />
exit(4);<br />
}<br />
}<br />
//Write to stdout (FD 1)<br />
if (FD_ISSET(1, &fdsWrite) && RBufLen > 0) {<br />
if (IncludePLen == 1) write(1, &RBufLen, 4);<br />
write(1, RBuf, RBufLen);<br />
RBufLen = 0;<br />
}<br />
}<br />
}<br />
</pre></div>
Admin