1160996Ssam/*- 2160996Ssam * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk> 3160996Ssam * All rights reserved. 4160996Ssam * 5160996Ssam * Redistribution and use in source and binary forms, with or without 6160996Ssam * modification, are permitted provided that the following conditions 7160996Ssam * are met: 8160996Ssam * 1. Redistributions of source code must retain the above copyright 9160996Ssam * notice, this list of conditions and the following disclaimer. 10160996Ssam * 2. Redistributions in binary form must reproduce the above copyright 11160996Ssam * notice, this list of conditions and the following disclaimer in the 12160996Ssam * documentation and/or other materials provided with the distribution. 13160996Ssam * 14160996Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15160996Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16160996Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17160996Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18160996Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19160996Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20160996Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21160996Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22160996Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23160996Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24160996Ssam * SUCH DAMAGE. 25160996Ssam * 26160996Ssam * $FreeBSD$ 27160996Ssam */ 28160996Ssam#include <sys/uio.h> 29160996Ssam#include <sys/types.h> 30160996Ssam#include <sys/socket.h> 31160996Ssam#include <netinet/in_systm.h> 32160996Ssam#include <netinet/in.h> 33160996Ssam#include <arpa/inet.h> 34160996Ssam#include <netinet/ip.h> 35160996Ssam#include <stdio.h> 36160996Ssam#include <stdlib.h> 37160996Ssam#include <string.h> 38160996Ssam#include <unistd.h> 39160996Ssam#include <fcntl.h> 40160996Ssam#include <errno.h> 41160996Ssam#include <signal.h> 42160996Ssam#include <err.h> 43160996Ssam 44160996Ssamvoid hexdump(void *b, int len) 45160996Ssam{ 46160996Ssam unsigned char *p = (unsigned char*) b; 47160996Ssam 48160996Ssam while (len--) 49160996Ssam printf("%.2X ", *p++); 50160996Ssam printf("\n"); 51160996Ssam} 52160996Ssam 53160996Ssamint handle_data(int dude, char *buf, int len) 54160996Ssam{ 55160996Ssam struct ip *ih; 56160996Ssam unsigned short id; 57160996Ssam char tmp[4]; 58160996Ssam struct iovec iov[2]; 59160996Ssam struct msghdr mh; 60160996Ssam 61160996Ssam ih = (struct ip*) buf; 62160996Ssam 63160996Ssam /* XXX IP FRAGS */ 64160996Ssam 65160996Ssam /* filter */ 66160996Ssam if (ih->ip_p != 0) 67160996Ssam return 0; 68160996Ssam 69160996Ssam if (ih->ip_hl != 5) 70160996Ssam return 0; 71160996Ssam 72160996Ssam /* get info */ 73160996Ssam id = ih->ip_id; 74160996Ssam len -= 20; 75160996Ssam buf += 20; 76160996Ssam printf("Got %d bytes [%d]\n", len, ntohs(id)); 77160996Ssam#if 0 78160996Ssam hexdump(buf, len); 79160996Ssam#endif 80160996Ssam 81160996Ssam /* prepare packet */ 82160996Ssam memcpy(tmp, &id, 2); 83160996Ssam id = htons(len); 84160996Ssam memcpy(&tmp[2], &id, 2); 85160996Ssam 86160996Ssam iov[0].iov_base = tmp; 87160996Ssam iov[0].iov_len = 4; 88160996Ssam iov[1].iov_base = buf; 89160996Ssam iov[1].iov_len = len; 90160996Ssam 91160996Ssam memset(&mh, 0, sizeof(mh)); 92160996Ssam mh.msg_iov = iov; 93160996Ssam mh.msg_iovlen = sizeof(iov)/sizeof(struct iovec); 94160996Ssam 95160996Ssam /* write */ 96160996Ssam if (sendmsg(dude, &mh, 0) != (4 + len)) 97160996Ssam return -1; 98160996Ssam return 0; 99160996Ssam} 100160996Ssam 101160996Ssamvoid handle_dude(int dude, int raw) 102160996Ssam{ 103160996Ssam char buf[4096]; 104160996Ssam int rd; 105160996Ssam 106160996Ssam while (1) { 107160996Ssam rd = recv(raw, buf, sizeof(buf), 0); 108160996Ssam if (rd == -1) 109160996Ssam err(1, "recv()"); 110160996Ssam 111160996Ssam if (handle_data(dude, buf, rd) == -1) 112160996Ssam return; 113160996Ssam } 114160996Ssam} 115160996Ssam 116160996Ssamvoid hand(int s) 117160996Ssam{ 118160996Ssam printf("sigpipe\n"); 119160996Ssam} 120160996Ssam 121160996Ssamint main(int argc, char *argv[]) 122160996Ssam{ 123160996Ssam int s, dude; 124160996Ssam struct sockaddr_in s_in; 125160996Ssam int len; 126160996Ssam int raw; 127160996Ssam 128160996Ssam memset(&s_in, 0, sizeof(&s_in)); 129160996Ssam s_in.sin_family = PF_INET; 130160996Ssam s_in.sin_port = htons(666); 131160996Ssam s_in.sin_addr.s_addr = INADDR_ANY; 132160996Ssam 133160996Ssam if ((raw = socket(PF_INET, SOCK_RAW, 0)) == -1) 134160996Ssam err(1, "socket()"); 135160996Ssam 136160996Ssam if ((s = socket(s_in.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1) 137160996Ssam err(1, "socket()"); 138160996Ssam 139160996Ssam if (bind(s, (struct sockaddr*)&s_in, sizeof(s_in)) == -1) 140160996Ssam err(1, "bind()"); 141160996Ssam 142160996Ssam if (listen(s, 5) == -1) 143160996Ssam err(1, "listen()"); 144160996Ssam 145160996Ssam if (signal(SIGPIPE, hand) == SIG_ERR) 146160996Ssam err(1, "signal()"); 147160996Ssam 148160996Ssam while (1) { 149160996Ssam len = sizeof(s_in); 150160996Ssam dude = accept(s, (struct sockaddr*)&s_in, &len); 151160996Ssam if (dude == -1) 152160996Ssam err(1, "accept()"); 153160996Ssam 154160996Ssam printf("Got dude %s\n", inet_ntoa(s_in.sin_addr)); 155160996Ssam handle_dude(dude, raw); 156160996Ssam printf("Done\n"); 157160996Ssam } 158160996Ssam} 159