From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sfi-mx-4.v28.ch3.sourceforge.com ([172.29.28.124] helo=mx.sourceforge.net) by 3yr0jf1.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1MOxon-0008Uu-KW for user-mode-linux-devel@lists.sourceforge.net; Thu, 09 Jul 2009 17:54:01 +0000 Received: from mail.unilim.fr ([164.81.1.45] helo=smtp.unilim.fr) by 1b2kzd1.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.69) id 1MOxom-0002SQ-6m for user-mode-linux-devel@lists.sourceforge.net; Thu, 09 Jul 2009 17:54:01 +0000 Received: from [192.168.1.10] (APoitiers-754-1-31-147.w86-207.abo.wanadoo.fr [86.207.250.147]) (authenticated bits=0) by smtp.unilim.fr (8.13.1/8.13.1) with ESMTP id n69HUVEp028645 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 9 Jul 2009 19:30:32 +0200 Message-ID: <4A562937.3090600@unilim.fr> Date: Thu, 09 Jul 2009 19:30:31 +0200 From: Julien Iguchi-Cartigny MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------040705080104000903060800" Subject: [uml-devel] Support for dumping trafic in uml_switch List-Id: The user-mode Linux development list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: user-mode-linux-devel-bounces@lists.sourceforge.net To: user-mode-linux-devel@lists.sourceforge.net This is a multi-part message in MIME format. --------------040705080104000903060800 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hello, This is a simple patch for uml tools with a program (uml_dump) which can connect to instance of uml_switch and then dump packets in cap format. Very useful to see communications between uml instances in wireshark or tcpdump. Cheers, Julien, Benoit and Jean-paul. --------------040705080104000903060800 Content-Type: text/x-patch; name="uml_dump.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="uml_dump.patch" diff -rupN tools-original/Makefile tools/Makefile --- tools-original/Makefile 2004-04-08 03:42:59.000000000 +0200 +++ tools/Makefile 2009-05-01 23:31:00.106571852 +0200 @@ -1,7 +1,7 @@ TUNCTL = $(shell [ -e /usr/include/linux/if_tun.h ] && echo tunctl) SUBDIRS = jail jailtest humfsify mconsole moo port-helper $(TUNCTL) uml_net \ - uml_router watchdog + uml_router watchdog uml_dump UMLVER = $(shell date +%Y%m%d) TARBALL = uml_utilities_$(UMLVER).tar BIN_DIR = /usr/bin diff -rupN tools-original/uml_dump/Makefile tools/uml_dump/Makefile --- tools-original/uml_dump/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ tools/uml_dump/Makefile 2009-05-01 23:31:15.860900482 +0200 @@ -0,0 +1,17 @@ +OBJS = uml_dump.o +BIN = uml_dump +CFLAGS = -g -Wall + +BIN_DIR ?= /usr/bin + +all : $(BIN) + +$(BIN) : $(OBJS) + $(CC) $(CFLAGS) -o $(BIN) $(OBJS) + +clean : + rm -f $(BIN) $(OBJS) *~ + +install : $(BIN) + install -d $(DESTDIR)$(BIN_DIR) + install -s $(BIN) $(DESTDIR)$(BIN_DIR) diff -rupN tools-original/uml_dump/uml_dump.c tools/uml_dump/uml_dump.c --- tools-original/uml_dump/uml_dump.c 1970-01-01 01:00:00.000000000 +0100 +++ tools/uml_dump/uml_dump.c 2009-05-17 13:42:58.692577826 +0200 @@ -0,0 +1,276 @@ +/* + * Copyright 2008 + * Authors: + * - Julien Iguchi-Cartigny + * - Jean-Baptiste Machemie + * - Benoit Bitarelle + * Licensed under the GPL + * + * TODO: receive packets from multiple uml switchs + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../uml_router/switch.h" +#include "../uml_router/uml_switch.h" +#include "../uml_router/port.h" + +/***************** PCAP Part *****************/ + +int output_fd; + +unsigned char pcap_file_header[] = { + 0xd4, 0xc3, 0xb2, 0Xa1, // magic number + 0x02, 0x00, 0x04, 0x00, // major and minor version number: 2.4 + 0x00, 0x00, 0x00, 0x00, // thiszone: GMT + 0x00, 0x00, 0x00, 0x00, // accuracy: 0 + 0xEA, 0x05, 0x00, 0x00, // max length of captured packet: 1514 + 0x01, 0x00, 0x00, 0x00 // data link type: ethernet +}; + +unsigned int pcap_packet_header[] = { + 0, // timestamp second + 0, // timestamp microsecond + 0, // number of octets of packet saved in file + 0 // actual length of packet +}; + +struct timeval tv; + +void dump_packet(struct packet *packet, int size) { + + int w; + + gettimeofday(&tv, (void*)0); + + pcap_packet_header[0] = tv.tv_sec; + pcap_packet_header[1] = tv.tv_usec; + pcap_packet_header[2] = size; + pcap_packet_header[3] = size; + + w = fwrite(pcap_packet_header, sizeof(unsigned char), + sizeof(pcap_packet_header), stdout); + + if(w<=0) + perror("error when writing packet header to stdout"); + + w = fwrite((unsigned char*)packet, sizeof(unsigned char), size, stdout); + + if(w<=0) + perror("error when writing packet data to stdout"); + + w = fflush(stdout); + + if(w!=0) + perror("error flushing stdout"); +} + +/***************** UML Part *****************/ + +static char *prog; + +static char *ctl_socket = "/tmp/uml.ctl"; + +int connect_fd, data_out_fd, data_in_fd; + +void cleanup() { + close(connect_fd); + close(data_out_fd); +} + +static void sig_handler(int sig) +{ + fprintf(stderr,"Caught signal %d, cleaning up and exiting\n", sig); + cleanup(); + signal(sig, SIG_DFL); + kill(getpid(), sig); +} + +static void usage(void) +{ + fprintf(stderr, "Usage : %s control-socket\n" + "if no parameter %s is used as control socket\n", + prog, ctl_socket); + exit(1); +} + + +int main(int argc, char *argv[]) { + + prog = argv[0]; + argv++; + argc--; + + /* parameter -help */ + if(argc == 1) { + + if(!strcmp(argv[0], "-help")){ + usage(); + } + + ctl_socket = argv[0]; + } + + if(argc > 1) { + usage(); + } + + /* ask for the data in socket */ + if((data_in_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0){ + perror("socket"); + exit(1); + } + + if(fcntl(data_in_fd, F_SETFL, O_NONBLOCK) < 0){ + perror("setting O_NONBLOCK on data in fd"); + exit(1); + } + + /* prepare the data in structure */ + struct sockaddr_un data_in_sun; + + struct { + char zero; + int pid; + int usecs; + } name; + + struct timeval tv; + + name.zero = 0; + name.pid = getpid(); + gettimeofday(&tv, NULL); + name.usecs = tv.tv_usec; + + data_in_sun.sun_family = AF_UNIX; + memcpy(data_in_sun.sun_path, &name, sizeof(name)); + + /* bind data_in_socket */ + if(bind(data_in_fd, (struct sockaddr*) &data_in_sun, + sizeof(data_in_sun)) < 0){ + perror("binding to data in socket"); + exit(1); + } + + /* ask for the connect socket */ + if((connect_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){ + perror("socket connect"); + exit(1); + } + + /* start the connect socket */ + struct sockaddr_un connect_sun; + + connect_sun.sun_family = AF_UNIX; + strncpy(connect_sun.sun_path, ctl_socket, sizeof(connect_sun.sun_path)); + + if(connect(connect_fd, (struct sockaddr *)&connect_sun, + sizeof(connect_sun)) < 0){ + perror("connect connect"); + fprintf(stderr,"check the path to control socket: %s\n", ctl_socket); + exit(1); + } + + /* prepare the request */ + struct request_v3 request; + request.magic = 0xfeedface; + request.version = 3; + request.type = REQ_NEW_DUMP; + request.sock = data_in_sun; + + int n; + + /* send the request */ + n = send(connect_fd, &request, sizeof(request), 0); + + if(n < sizeof(request)) { + fprintf(stderr,"not enough byte sent or error: %d\n", n); + exit(1); + } + + /* receive the data out socket addr (we don't really care about it) */ + struct sockaddr_un data_out_sun; + + n = recv(connect_fd, &data_out_sun, sizeof(data_out_sun), 0); + + if(n < sizeof(data_out_sun)) { + fprintf(stderr,"not enough byte received or error: %d\n", n); + exit(1); + } + + /* prepare the pool */ + struct pollfd p[2]; + + p[0].fd = connect_fd; + p[0].events = POLLIN; + p[1].fd = data_in_fd; + p[1].events = POLLIN; + + /* setup the signal handler for CTRL-C */ + if(signal(SIGINT, sig_handler) < 0) + perror("Setting handler for SIGINT"); + + /* setup the signal handler for closed pipe by reader */ + if(signal(SIGPIPE, sig_handler) < 0) + perror("Setting handler for SIGPIPE"); + + /* writing pcap header to stdout */ + int w = fwrite(pcap_file_header, sizeof(unsigned char), + sizeof(pcap_file_header), stdout); + + if(w<=0) + perror("error when writing cap header to stdout"); + + struct packet packet; + + /* the main loop */ + while(1) { + + /* waiting */ + n = poll(p, 2, -1); + + if(n < 0){ + if(errno == EINTR) continue; /* if poll stop by a signal */ + perror("poll"); + break; + } + + /* check control socket */ + if(p[0].revents) { + if(p[0].revents & POLLHUP){ + fprintf(stderr,"uml_switch disconnected\n"); + break; + } else { + fprintf(stderr,"control packet in excess ?\n"); + exit(1); + } + } + + /* check data out socket */ + if(p[1].revents) { + + n = recv(data_in_fd, &packet, sizeof(packet), 0); + if(n < 0 && errno != EAGAIN) { + perror("recv data out socket\n"); + exit(1); + } + + dump_packet(&packet,n); + } + } + + cleanup(); + + return 0; +} diff -rupN tools-original/uml_router/Makefile tools/uml_router/Makefile --- tools-original/uml_router/Makefile 2003-02-19 01:16:27.000000000 +0100 +++ tools/uml_router/Makefile 2009-05-01 23:31:20.088977298 +0200 @@ -1,6 +1,6 @@ TUNTAP = $(shell [ -e /usr/include/linux/if_tun.h ] && echo -DTUNTAP) -OBJS = hash.o port.o uml_switch.o +OBJS = hash.o port.o uml_switch.o BIN = uml_switch CFLAGS = -g -Wall $(TUNTAP) diff -rupN tools-original/uml_router/port.c tools/uml_router/port.c --- tools-original/uml_router/port.c 2003-03-12 17:35:03.000000000 +0100 +++ tools/uml_router/port.c 2009-05-01 23:31:20.593666238 +0200 @@ -8,25 +8,6 @@ #include "hash.h" #include "port.h" -struct packet { - struct { - unsigned char dest[ETH_ALEN]; - unsigned char src[ETH_ALEN]; - unsigned char proto[2]; - } header; - unsigned char data[1500]; -}; - -struct port { - struct port *next; - struct port *prev; - int control; - void *data; - int data_len; - unsigned char src[ETH_ALEN]; - void (*sender)(int fd, void *packet, int len, void *data); -}; - static struct port *head = NULL; #define IS_BROADCAST(addr) ((addr[0] & 1) == 1) @@ -107,7 +88,16 @@ static void send_dst(struct port *port, (*p->sender)(p->control, packet, len, p->data); } } - else (*target->sender)(target->control, packet, len, target->data); + else { + + /* looking for dump port */ + for(p = head; p != NULL; p = p->next){ + if(p == port) continue; + if(p->dump) + (*p->sender)(p->control, packet, len, p->data); + } + (*target->sender)(target->control, packet, len, target->data); + } } static void handle_data(int fd, int hub, struct packet *packet, int len, @@ -149,7 +139,7 @@ void handle_tap_data(int fd, int hub) } int setup_port(int fd, void (*sender)(int fd, void *packet, int len, - void *data), void *data, int data_len) + void *data), void *data, int data_len, int dump) { struct port *port; @@ -165,6 +155,7 @@ int setup_port(int fd, void (*sender)(in port->data = data; port->data_len = data_len; port->sender = sender; + port->dump = dump; head = port; printf("New connection\n"); return(0); @@ -215,7 +206,7 @@ void handle_sock_data(int fd, int hub) handle_data(fd, hub, &packet, len, &data, match_sock); } -int setup_sock_port(int fd, struct sockaddr_un *name, int data_fd) +int setup_sock_port(int fd, struct sockaddr_un *name, int data_fd, int dump) { struct sock_data *data; @@ -226,7 +217,7 @@ int setup_sock_port(int fd, struct socka } *data = ((struct sock_data) { fd : data_fd, sock : *name }); - return(setup_port(fd, send_sock, data, sizeof(*data))); + return(setup_port(fd, send_sock, data, sizeof(*data), dump)); } static void service_port(struct port *port) @@ -235,9 +226,12 @@ static void service_port(struct port *po char c; n = read(port->control, &c, sizeof(c)); - if(n < 0) perror("Reading request"); - else if(n == 0) printf("Disconnect\n"); - else printf("Bad request\n"); + if(n < 0) + perror("Reading request"); + else if(n == 0) + printf("Disconnect\n"); + else + printf("Bad request\n"); } int handle_port(int fd) @@ -252,4 +246,3 @@ int handle_port(int fd) } return(1); } - diff -rupN tools-original/uml_router/port.h tools/uml_router/port.h --- tools-original/uml_router/port.h 2002-04-10 22:08:09.000000000 +0200 +++ tools/uml_router/port.h 2009-05-01 23:31:20.717552166 +0200 @@ -8,12 +8,32 @@ #include #include +struct packet { + struct { + unsigned char dest[ETH_ALEN]; + unsigned char src[ETH_ALEN]; + unsigned char proto[2]; + } header; + unsigned char data[1500]; +}; + +struct port { + struct port *next; + struct port *prev; + int control; + void *data; + int data_len; + unsigned char src[ETH_ALEN]; + void (*sender)(int fd, void *packet, int len, void *data); + int dump; +}; + extern int handle_port(int fd); extern void close_port(int fd); -extern int setup_sock_port(int fd, struct sockaddr_un *name, int data_fd); +extern int setup_sock_port(int fd, struct sockaddr_un *name, int data_fd, int dump); extern int setup_port(int fd, void (*sender)(int fd, void *packet, int len, void *data), void *data, - int data_len); + int data_len, int dump); extern void handle_tap_data(int fd, int hub); extern void handle_sock_data(int fd, int hub); diff -rupN tools-original/uml_router/tuntap.c tools/uml_router/tuntap.c --- tools-original/uml_router/tuntap.c 2002-04-27 19:02:16.000000000 +0200 +++ tools/uml_router/tuntap.c 2009-05-01 23:31:21.088773438 +0200 @@ -6,6 +6,7 @@ #include #include #include +#include "switch.h" #include "port.h" static void send_tap(int fd, void *packet, int len, void *unused) @@ -35,7 +36,7 @@ int open_tap(char *dev) close(fd); return(-1); } - err = setup_port(fd, send_tap, NULL, 0); + err = setup_port(fd, send_tap, NULL, 0, 0); if(err) return(err); return(fd); } diff -rupN tools-original/uml_router/uml_switch.c tools/uml_router/uml_switch.c --- tools-original/uml_router/uml_switch.c 2003-09-03 22:16:32.000000000 +0200 +++ tools/uml_router/uml_switch.c 2009-05-01 23:31:21.665168486 +0200 @@ -7,9 +7,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -19,6 +17,7 @@ #ifdef TUNTAP #include "tuntap.h" #endif +#include "uml_switch.h" #ifdef notdef #include @@ -26,58 +25,6 @@ static int hub = 0; static int compat_v0 = 0; - -enum request_type { REQ_NEW_CONTROL }; - -struct request_v0 { - enum request_type type; - union { - struct { - unsigned char addr[ETH_ALEN]; - struct sockaddr_un name; - } new_control; - } u; -}; - -#define SWITCH_MAGIC 0xfeedface - -struct request_v1 { - uint32_t magic; - enum request_type type; - union { - struct { - unsigned char addr[ETH_ALEN]; - struct sockaddr_un name; - } new_control; - } u; -}; - -struct request_v2 { - uint32_t magic; - uint32_t version; - enum request_type type; - struct sockaddr_un sock; -}; - -struct reply_v2 { - unsigned char mac[ETH_ALEN]; - struct sockaddr_un sock; -}; - -struct request_v3 { - uint32_t magic; - uint32_t version; - enum request_type type; - struct sockaddr_un sock; -}; - -union request { - struct request_v0 v0; - struct request_v1 v1; - struct request_v2 v2; - struct request_v3 v3; -}; - static char *ctl_socket = "/tmp/uml.ctl"; static char *data_socket = NULL; @@ -149,7 +96,11 @@ static void new_port_v0(int fd, struct r { switch(req->type){ case REQ_NEW_CONTROL: - setup_sock_port(fd, &req->u.new_control.name, data_fd); + setup_sock_port(fd, &req->u.new_control.name, data_fd, 0); + break; + case REQ_NEW_DUMP: + printf("REQ_NEW_DUMP for version 0 not supported\n"); + close_descriptor(fd); break; default: printf("Bad request type : %d\n", req->type); @@ -164,7 +115,8 @@ static void new_port_v1_v3(int fd, enum switch(type){ case REQ_NEW_CONTROL: - err = setup_sock_port(fd, sock, data_fd); + case REQ_NEW_DUMP: + err = setup_sock_port(fd, sock, data_fd, (type == REQ_NEW_DUMP)); if(err) return; n = write(fd, &data_sun, sizeof(data_sun)); if(n != sizeof(data_sun)){ @@ -203,14 +155,28 @@ static void new_port(int fd, int data_fd return; } if(req.v1.magic == SWITCH_MAGIC){ - if(req.v2.version == 2) new_port_v2(fd, &req.v2, data_fd); + + /* version 2*/ + if(req.v2.version == 2) + new_port_v2(fd, &req.v2, data_fd); + + /* version 3 */ if(req.v3.version == 3) new_port_v1_v3(fd, req.v3.type, &req.v3.sock, data_fd); + + /* version unknow */ else if(req.v2.version > 2) fprintf(stderr, "Request for a version %d port, which this " "uml_switch doesn't support\n", req.v2.version); + + /* version 1 */ + else if(req.v1.type == REQ_NEW_DUMP) + fprintf(stderr, "REQ_NEW_DUMP request for version 1, which this " + "uml_switch doesn't support\n"); else new_port_v1_v3(fd, req.v1.type, &req.v1.u.new_control.name, data_fd); } + + /* version 0*/ else new_port_v0(fd, &req.v0, data_fd); } @@ -528,6 +494,8 @@ int main(int argc, char **argv) } for(i = 0; i < nfds; i++){ if(fds[i].revents == 0) continue; + + /* stdin */ if(fds[i].fd == 0){ if(fds[i].revents & POLLHUP){ printf("EOF on stdin, cleaning up and exiting\n"); diff -rupN tools-original/uml_router/uml_switch.h tools/uml_router/uml_switch.h --- tools-original/uml_router/uml_switch.h 1970-01-01 01:00:00.000000000 +0100 +++ tools/uml_router/uml_switch.h 2009-05-01 23:31:21.784787672 +0200 @@ -0,0 +1,67 @@ +/* Copyright 2008 Jeff Dike & Kartoch + * Licensed under the GPL + */ + +#ifndef __UML_SWITCH_H__ +#define __UML_SWITCH_H__ + +#include +#include + +enum request_type { + REQ_NEW_CONTROL, + REQ_NEW_DUMP +}; + +struct request_v0 { + enum request_type type; + union { + struct { + unsigned char addr[ETH_ALEN]; + struct sockaddr_un name; + } new_control; + } u; +}; + +#define SWITCH_MAGIC 0xfeedface + +struct request_v1 { + uint32_t magic; + enum request_type type; + union { + struct { + unsigned char addr[ETH_ALEN]; + struct sockaddr_un name; + } new_control; + } u; +}; + +struct request_v2 { + uint32_t magic; + uint32_t version; + enum request_type type; + struct sockaddr_un sock; +}; + +struct reply_v2 { + unsigned char mac[ETH_ALEN]; + struct sockaddr_un sock; +}; + +struct request_v3 { + uint32_t magic; + uint32_t version; + enum request_type type; + struct sockaddr_un sock; +}; + +union request { + struct request_v0 v0; + struct request_v1 v1; + struct request_v2 v2; + struct request_v3 v3; +}; + +#endif + + --------------040705080104000903060800 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge --------------040705080104000903060800 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ User-mode-linux-devel mailing list User-mode-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel --------------040705080104000903060800--