📄 vapornet.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/lib/vapornet.c,v 1.2 2001/11/08 15:56:31 tneale Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** * Copyright 1995-1997 Epilogue Technology Corporation. * Copyright 1998 Integrated Systems, Inc. * All rights reserved. ****************************************************************************//* * $Log: vapornet.c,v $ * Revision 1.2 2001/11/08 15:56:31 tneale * Updated for newest file layout * * Revision 1.1.1.1 2001/11/05 17:48:44 tneale * Tornado shuffle * * Revision 2.28 2001/04/24 14:40:26 josh * remove an extra character * * Revision 2.27 2001/01/19 22:23:56 paul * Update copyright. * * Revision 2.26 2000/10/16 19:21:56 paul * Restore sockets and mempool code. * * Revision 2.25 2000/03/17 00:12:49 meister * Update copyright message * * Revision 2.24 2000/03/13 21:22:16 paul * Removed some code that we are no longer working on. * * Revision 2.23 1999/11/05 22:29:08 paul * Updated driver structs to reflect conditional backwards-compatibility * fields and new fields. * * Revision 2.22 1999/04/28 23:53:26 sra * Clean up various minor installation option glitches. * * Revision 2.21 1999/04/26 19:04:58 sra * Fix a few minor warnings, fix a few Solaris-specific problems in the * demo code. * * Revision 2.20 1998/12/07 19:49:37 josh * making vapornet support unnumbered links * * Revision 2.19 1998/09/18 19:56:24 meister * timer call renaming tm_ --> etc_tm_ * * Revision 2.18 1998/06/03 21:23:07 sar * Updated code to use common string macros * * Revision 2.17 1998/05/18 17:21:22 meister * "struct route *" --> "route_entry_t *" * * Revision 2.16 1998/02/25 04:57:45 sra * Update copyrights. * * Revision 2.15 1997/05/17 23:08:56 sra * Clean up some SunOS/gcc warnings. * * Revision 2.14 1997/03/20 06:53:18 sra * DFARS-safe copyright text. Zap! * * Revision 2.13 1997/03/19 22:38:29 sra * Silence a gcc warning. * * Revision 2.12 1997/02/25 10:58:16 sra * Update copyright notice, dust under the bed. * * Revision 2.11 1997/02/19 08:10:29 sra * More fun merging snmptalk into snark, general snark cleanup. * * Revision 2.10 1997/01/29 06:53:58 sra * Switch vapornet to use a media_ctl() function. * * Revision 2.9 1997/01/17 23:15:10 sra * Remove last vestiges of Attache 2.x compatability mode. * * Revision 2.8 1996/03/22 10:05:39 sra * Update copyrights prior to Attache 3.2 release. * * Revision 2.7 1996/03/08 21:54:58 sra * Add code for dropping/delaying packets to simulate bad networks. * Add timer-based checkpointing of pktlog files. * * Revision 2.6 1995/10/09 22:54:32 sra * Fun with copyright notices. * * Revision 2.5 1995/09/08 20:00:31 sra * Duh, need to call vp_broadcast() even for broadcast on ptop links, * since otherwise we drop the packet when we can't find the socket. * * Revision 2.4 1995/09/08 19:58:35 sra * Add WetStringNet, for testing OSPF over point-to-point links. * * Revision 2.3 1995/07/31 13:54:55 sra * OSPF now working well enough to let somebody else test it. * * Revision 2.2 1995/06/27 06:23:28 sra * Add multicast support. Claim to be 3MB-Ether so that RCI * code will believe this is a broadcast-capable medium. * * Revision 2.1 1995/05/13 04:22:24 sra * Get installation conditional right. * * Revision 2.0 1995/05/10 22:38:15 sra * Attache release 3.0. * * Revision 1.2 1995/05/06 00:41:42 sra * Put under installation conditional. * * Revision 1.1 1995/03/26 02:29:19 sra * Initial revision * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*//* * Fake network built on BSD "unix domain" sockets. Intended primarily * to allow building a complex enough network to do some testing of router * code in a relatively sane debugging environment. * * None of the code in this module is likely to be at all suitable for * use in a real product, it's just a debugging tool that Epilogue's * engineers use internally and that we're providing to our customers * as a courtesy. */#include <wrn/wm/attache/config.h>#include <wrn/wm/attache/mib.h>#include <wrn/wm/attache/timer.h>#include <wrn/wm/attache/packet.h>#include <wrn/wm/attache/net.h>#include <wrn/wm/attache/route.h>#include <wrn/wm/attache/ip.h>#include <wrn/wm/attache/slowtime.h>#include <wrn/wm/attache/glue.h>#if INSTALL_SNARK_BSD_VAPORNET/* Dunno what system include files we want yet */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <dirent.h>#include <errno.h>#include <fcntl.h>#include <sys/file.h>#include <unistd.h>#include <sys/stat.h>#include <sys/socket.h>#include <sys/un.h>#include <assert.h>#include <sys/time.h>#include <wrn/wm/demo/snarklib.h>#include <wrn/wm/demo/read_ini.h>#include <wrn/wm/demo/bsdif.h>#include <wrn/wm/demo/vapornet.h>/* * Maximum number of addresses we can handle for broadcast. */#ifndef VP_MAX_BROADCAST#define VP_MAX_BROADCAST 256#endif/* * Maximum number of interfaces we probe for. */#ifndef VP_MAX_INTERFACES#define VP_MAX_INTERFACES 10#endif#ifndef WS_MAX_INTERFACES#define WS_MAX_INTERFACES VP_MAX_INTERFACES#endif/* * Directory where vapornet socket inodes live. */#ifndef VP_SOCKET_DIR#define VP_SOCKET_DIR "/tmp/vapornet"#endifstatic char vp_socket_dir[] = VP_SOCKET_DIR;/* * Cycle time for synchronizing packet log to disk. */#ifndef VP_PKTLOG_SYNC_INTERVAL#define VP_PKTLOG_SYNC_INTERVAL 30000#endif/* * Section name for our configuration data. */static char attache_section[] = "etc attache";/* * Interface speed and MTU parameters. */#define VP_MTU 1500#define VP_SPEED 0x7FFFFFFF#define WS_MTU VP_MTU#define WS_SPEED VP_SPEED#define VP_MAX_TAG 20/* * Driver private data, hangs off net->specific->private. */struct vp_ctl { struct net *net; /* associated Attache network interface */ packet *ipkt; /* receive buffer (to avoid extra copy step) */ time_t bcast_mtime; /* last mod time for broadcast cache */ inaddr_t bcasts[VP_MAX_BROADCAST]; int nbcasts; /* broadcast address list for our subnet */ FILE *pktlog; /* packet log file, if non-null */ bits32_t delay, jitter; /* for simulating low-quality links */ bits32_t drop_p1, drop_p2, drop_p3, drop_count; packet *opkts; /* keep track of our garbage... */ struct timer pktlog_sync; /* for synching packet log file */ bits8_t local_tag[VP_MAX_TAG+1]; bits8_t remote_tag[VP_MAX_TAG+1]; bits8_t local_exists; bits8_t remote_exists;};/* * Junk that we want to keep around when delaying packet transmission * to simulate a bad link. By craming this stuff into the head of * the packet buffer, we avoid having to worry about storage issues. */struct vp_lnh { inaddr_t host; /* next hop */ struct timer tm; /* delay timer */};/* * Logging routines. We log packets in the same binary file format * as the excellent tcpdump program, so that we can use tcpdump itself * as the analysis tool. Thanks, Van! * * Some of the code in vp_open_log() and vp_log() comes from the tcpdump * program (because there's no other documentation for the dump file * format) and thus is subject to the following copyright: * * Copyright (c) 1990,1991 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. * * Please note that since Epilogue distributes this module solely as * sample source code on an "as-is" basis and does not advertise or * even document the features provided by these logging routines, we * believe that inclusion of the above notice constitutes compliance * with the copyright conditions. */#define TCPDUMP_MAGIC 0xa1b2c3d4#define TCPDUMP_VERSION_MAJOR 2#define TCPDUMP_VERSION_MINOR 2struct tcpdump_file_header { u_long magic; u_short version_major; u_short version_minor; long thiszone; u_long sigfigs; u_long snaplen; u_long linktype;};static void vp_pklog_sync_handler(struct timer *tm, void *cookie){ struct vp_ctl *ctl = cookie; if (ctl && ctl->pktlog) fflush(ctl->pktlog); etc_tm_set(tm, VP_PKTLOG_SYNC_INTERVAL);}static void vp_close_log(struct vp_ctl *ctl){ if (ctl->pktlog) { fclose(ctl->pktlog); ctl->pktlog = 0; } etc_tm_cancel(&ctl->pktlog_sync);}static void vp_open_log(struct vp_ctl *ctl, struct ini_handle *ini_handle){ char *filename, varname[20]; struct tcpdump_file_header hdr;#if !defined(INSTALL_on_solaris) || !INSTALL_on_solaris time_t t = time(0); struct tm *tm = localtime(&t);#endif sprintf(varname, "%s-pktfile", ctl->net->s_name); if ((filename = ini_lookup(ini_handle, attache_section, varname)) == 0 || (ctl->pktlog = fopen(filename, "w")) == 0) return; hdr.magic = TCPDUMP_MAGIC; hdr.version_major = TCPDUMP_VERSION_MAJOR; hdr.version_minor = TCPDUMP_VERSION_MINOR; hdr.snaplen = VP_MTU; hdr.sigfigs = 2; hdr.linktype = 0;#if !defined(INSTALL_on_solaris) || !INSTALL_on_solaris hdr.thiszone = tm ? tm->tm_gmtoff : 0;#else hdr.thiszone = 0;#endif if (fwrite(&hdr, sizeof(hdr), 1, ctl->pktlog) != 1) { vp_close_log(ctl); return; } ctl->pktlog_sync.handler = vp_pklog_sync_handler; ctl->pktlog_sync.cookie = ctl; etc_tm_set(&ctl->pktlog_sync, VP_PKTLOG_SYNC_INTERVAL);}struct tcpdump_packet_header { struct timeval ts; u_long len; u_long caplen; u_int af;};static void vp_log_packet(FILE *f, packet *p){ struct tcpdump_packet_header h; gettimeofday(&h.ts, 0); h.af = AF_INET; h.len = h.caplen = p->pkt_datalen + sizeof(h.af); fwrite(&h, sizeof(h), 1, f); fwrite(p->pkt_data, p->pkt_datalen, 1, f);}/* * Output routines. *//* * Send packet at head of output queue to a single recipient. * Just drops packets that can't be sent immediately. */static void vp_unicast(struct vp_ctl *ctl, packet *p, inaddr_t dest){ struct net *net = ctl->net; struct bsdif *bif = net->specific; struct sockaddr_un sa; sprintf(sa.sun_path, "%s/%s", vp_socket_dir, inettoa(dest)); sa.sun_family = AF_UNIX; sendto(bif->fd, (p->pkt_data), p->pkt_datalen, 0, (struct sockaddr *) &sa, sizeof(sa) - sizeof(sa.sun_path) + STRLEN(sa.sun_path));}/* * Send packet at head of output queue to a single recipient as * specified by the 'dest' identifier. */ static void vp_link_send(struct vp_ctl *ctl, packet *p){ struct net *net = ctl->net; struct bsdif *bif = net->specific; struct sockaddr_un sa; sprintf(sa.sun_path, "%s/%s", vp_socket_dir, ctl->remote_tag); sa.sun_family = AF_UNIX; sendto(bif->fd, (p->pkt_data), p->pkt_datalen, 0, (struct sockaddr *) &sa, sizeof(sa) - sizeof(sa.sun_path) + STRLEN(sa.sun_path));}/* * Simulate broadcast by iterative unicast in pseudo-random order. * We construct the broadcast list by looking for addresses that * are on a subnet attached to this interface but which are not * any of our own addresses. This is a little painful, but we * only have to do it when the socket directory changes. */void vp_broadcast(struct vp_ctl *ctl, packet *p){ struct net *net = ctl->net; int idx[VP_MAX_BROADCAST], i, n; route_entry_t *r; inaddr_t addr; struct dirent *dp; struct stat st; DIR *dd; if (stat(vp_socket_dir, &st) >= 0 && st.st_mtime > ctl->bcast_mtime && (dd = opendir(vp_socket_dir)) != 0) { n = 0; ctl->remote_exists = 0; while (n < VP_MAX_BROADCAST && (dp = readdir(dd)) != 0) { addr = atoinet(dp->d_name); if (addr) { /* Punt if we don't share a subnet with this address. */ r = owner_routes_first(&direct_routes_owner); while (r && (net != r->net || (addr & r->mask) != r->dest)) r = owner_routes_next(&direct_routes_owner, r); if (!r) continue; /* Punt if this is one of our own addresses. */ r = owner_routes_first(&address_routes_owner); while (r && addr != r->dest) r = owner_routes_next(&address_routes_owner, r); if (r) continue; /* An address on our subnet that's not us, save it. */ ctl->bcasts[n++] = addr; } else { /* could it be the other end of an unnumbered link? */ if ((ctl->remote_tag[0]) && !STRCMP(ctl->remote_tag, dp->d_name))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -