300分,一个我认为很难的问题(300分)

Z

zzzyq

Unregistered / Unconfirmed
GUEST, unregistred user!
如果你用过TCPVIEW, 可以知道当前的网络连接四元组的列表,并且可以知道每个本地相应进程的执行程序名,
我要做的就是实现相同的功能,分不够可以再加,但要求即使没有实现的具体代码,也应该要有可行得通的具体方案
 
http://www.sysinternals.com/ntw2k/source/tcpview.shtml
 
我有全部的 VC 源码。
 
/* http://www.cotse.com Fear the swimming Elephant! */

/**
** version : v1.01
** architecture: SunOS 4.1 [Sun3/Sun4]
** compilation : cc -O4 tcpw.c -o tcpw; strip tcpw
** source rights: this is an EXTREMELLY VICIOUS program, it is ADVISED
** that if you must keep this source online, KEEP IT IN ENCRYPTED
** FORM.
**/

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/stropts.h>
#include <sys/signal.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/nit_if.h>
#include <net/nit_buf.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>

char *malloc();
char *device;
int debug = 0, /* debug */
fastdump = 0, /* do no sequential packet processing */
oneway = 0; /* oneway watch */

char *ProgName;

#define NIT_DEV "/dev/nit"
#define CHUNKSIZE 4096 /* device buffer size */

int if_fd = -1;
int Packet[CHUNKSIZE + 32];

#define STREAM_NULL (0)
#define STREAM_STOD (1)
#define STREAM_DTOS (2)
#define STREAM_MAX (3)

struct PktStack {
u_char data[CHUNKSIZE];
int Len;
u_long Seq;
};

#define STACK_MAX (10)

struct PktStack pkt_stack[STREAM_MAX][STACK_MAX];
int pkt_snum[STREAM_MAX];
u_long seq_num[STREAM_MAX];
char *Hostname[STREAM_MAX];
struct in_addr IPaddr[STREAM_MAX];
int TCPport[STREAM_MAX];

#define ISeq(s,d) ((s) == (d))
#define ISneq(s,d) ((s) != (d))

void
Pexit(err, msg)
int err;
char *msg;
{
perror(msg);
exit(err);
}

void
Zexit(err, msg)
int err;
char *msg;
{
fprintf(stderr, msg);
exit(err);
}

#define FREEstk(SK,St,Rc) {
SK.Len = (-1);
if(!(--pkt_snum[St]))
return(Rc);
}
#define ALLOCstk(SK,Len,Data,S,St) {
bcopy(Data,SK.data,Len);
SK.Len = Len;
SK.Seq = S;
pkt_snum[St]++;
}
#define pr_packet(p,length) {
while(length-- >0)
fputc(*p++,stdout);
fflush(stdout);
}
#define MAL_pr_packet(i_p,i_length) {
register u_char *p = i_p;
register int length = i_length;
pr_packet(p,length);
}
#define DEBUGstk(Msg,Num,Seq) if(debug) {
printf(Msg,Num,Seq); fflush(stdout);
}
#define SPKT pkt_stack[Tp]

/* find and print any packets in the stack IF they are sequential
* after ours
*/
int
cpr_stack(Tp)
register int Tp;
{
register int i, pr = 1;

while (pr)
for (pr = i = 0; (i < STACK_MAX) && (!pr); i++) {
if (ISneq(SPKT.Len, (-1))) {
if (SPKT.Seq <= seq_num[Tp]) { /* check for old packets */
DEBUGstk("DISCARD(%d/%08X)/n",
pkt_snum[Tp], SPKT.Seq);
FREEstk(SPKT, Tp, 0);
} else if (ISeq(SPKT.Seq, (seq_num[Tp] + 1))) { /* check for ours! */
DEBUGstk("POP(%d/%08X/n", pkt_snum[Tp], SPKT.Seq);
seq_num[Tp] = SPKT.Seq;
MAL_pr_packet(SPKT.data, SPKT.Len);
FREEstk(SPKT, Tp, 0);
pr = 1;
}
}
}
}

/* push packet onto stack, also checking for overflow, if so, dump
* the stack [missing packet assumed unrecoverable] */
int
psh_stack(S, Tp, p, Len)
register u_long S;
register int Tp, Len;
register u_char *p;
{
register
int i = 0;
register struct PktStack *PK = NULL;

for (; (i < STACK_MAX); i++) {
if (ISneq(SPKT.Len, (-1))) {
if (ISeq(SPKT.Seq, S))
return (0); /* that Seqnum is already on the stack */
} else if (ISeq(PK, NULL)) {
PK = &SPKT;
}
}
/* its not on the stack and we got a position for it */
if (ISneq(PK, NULL)) {
DEBUGstk("PUSH(%d/%08X)/n", pkt_snum[Tp], S);
bcopy(p, PK->data, Len);
PK->Len = Len;
PK->Seq = S;
pkt_snum[Tp]++;
return (0);
} {
/* if we reach here, stack is full, assume missing packet is
* gone forever, so just dump now .. */
register int j;
register u_long CS;

while (1) {
j = (STACK_MAX + 2);
CS = ~(0); /* determine lowest seq number */
for (i = 0; (i < STACK_MAX); i++) {
if (ISneq(SPKT.Len, (-1)) && (SPKT.Seq <= CS)) {
CS = SPKT.Seq;
j = i;
}
} /* must be nothing in stack */
if (j > STACK_MAX)
return (1); /* print */
seq_num[Tp] = SPKT.Seq;
DEBUGstk("FLUSH(%d/%08X)/n", pkt_snum[Tp], SPKT.Seq);
MAL_pr_packet(SPKT.data, SPKT.Len);
FREEstk(SPKT, Tp, 1);
}
}
}

#define IP ((struct ip *)Packet)
#define IP_OFFSET (0x1FFF)
#define SZETH (sizeof(struct ether_header))
#define IPLEN (ntohs(ip->ip_len))
#define IPHLEN (ip->ip_hl)
#define ADneq(s,t) ((s).s_addr != (t).s_addr)

/* important part of the prog, determines if a packet is one
* we want, and performs sycnhing of sequence numbers */
void
filter(cp, pktlen)
char *cp;
u_int pktlen;
{
register int Stream = STREAM_NULL;
register struct ip *ip;
register struct tcphdr *tcph;
register u_long CurSEQ;
register u_char *p;

{
register u_short EtherType = ntohs(((struct ether_header *) cp)->ether_type);

if (EtherType < 0x600) {
EtherType = *(u_short *) (cp + SZETH + 6);
cp += 8;
pktlen -= 8;
}
if (ISneq(EtherType, ETHERTYPE_IP))
return;
}
/* ugh, gotta do an alignment :-( */
bcopy(cp + SZETH, (char *) Packet, (int) (pktlen - SZETH));
ip = (struct ip *) Packet;
if (ISneq(ip->ip_p, IPPROTO_TCP))
return;
tcph = (struct tcphdr *) (Packet + IPHLEN);
CurSEQ = (ntohl(tcph->th_seq));
if (debug) {
printf("SRC:%s(%d) ", inet_ntoa(ip->ip_src), tcph->th_sport);
printf("DST:%s(%d)/n", inet_ntoa(ip->ip_dst), tcph->th_dport);
}
if (ISeq(tcph->th_sport, TCPport[STREAM_STOD]) &&
ISeq(tcph->th_dport, TCPport[STREAM_DTOS])) {
if (ADneq(ip->ip_src, IPaddr[STREAM_STOD]) ||
ADneq(ip->ip_dst, IPaddr[STREAM_DTOS]))
return;
if (!seq_num[Stream = STREAM_STOD]) {
seq_num[STREAM_STOD] = CurSEQ - 1;
printf("Hooked S->D [Seq %08X] .../n", CurSEQ);
} else if (CurSEQ <= seq_num[STREAM_STOD])
return;
} else if ((!oneway) &&
ISeq(tcph->th_sport, TCPport[STREAM_DTOS]) &&
ISeq(tcph->th_dport, TCPport[STREAM_STOD])) {
if (ADneq(ip->ip_src, IPaddr[STREAM_DTOS]) ||
ADneq(ip->ip_dst, IPaddr[STREAM_STOD]))
return;
if (!seq_num[Stream = STREAM_DTOS]) {
seq_num[STREAM_DTOS] = CurSEQ - 1;
printf("Hooked D->S [Seq %08X] .../n", CurSEQ);
} else if (CurSEQ <= seq_num[STREAM_DTOS])
return;
} else
return;
{
register int length = ((IPLEN - (IPHLEN * 4)) - (tcph->th_off * 4));

if (debug)
printf("[%s]Seq=%08X,pl=%04X,dl=%04X,l=%04X,iph=%04X,ipl=%04X,tf=%04X/n",
(Stream == STREAM_STOD) ? " S / D " : " D / S ", CurSEQ, pktlen,
(IPLEN - (IPHLEN * 4)), length, ip->ip_hl, ip->ip_len, tcph->th_off);
p = (u_char *) Packet;
p += ((ip->ip_hl * 4) + (tcph->th_off * 4));
if (fastdump) {
pr_packet(p, length);
} else {
re_loop:if (ISeq(CurSEQ, (seq_num[Stream] + 1))) {
seq_num[Stream] = CurSEQ;
pr_packet(p, length);
if (pkt_snum[Stream]) /* check for 'stacked' packets */
cpr_stack(Stream);
} else {
/* out of sequence packet */
if (psh_stack(CurSEQ, Stream, p, length))
goto re_loop;
}
}
}
}

/* signal handler */
void
flushit()
{
printf("/n/n[terminating]/n");
fflush(stdout);
exit(1);
}

/* opens network interface, performs ioctls and reads from it,
* passing data to filter function */
void
do_it()
{
int cc;
char *buf;

u_short sp_ts_len;

if (!(buf = malloc(CHUNKSIZE)))
Pexit(1, "Eth: malloc");
/* this /dev/nit initialization code pinched from etherfind */ {
struct strioctl si;
struct ifreq ifr;
struct timeval timeout;
u_int chunksize = CHUNKSIZE;
u_long if_flags = NI_PROMISC;

if ((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
Pexit(1, "Eth: nit open");
if (ioctl(if_fd, I_SRDOPT, (char *) RMSGD) < 0)
Pexit(1, "Eth: ioctl (I_SRDOPT)");
si.ic_timout = INFTIM;
if (ioctl(if_fd, I_PUSH, "nbuf") < 0)
Pexit(1, "Eth: ioctl (I_PUSH /"nbuf/")");
timeout.tv_sec = 1;
timeout.tv_usec = 0;
si.ic_cmd = NIOCSTIME;
si.ic_len = sizeof (timeout);
si.ic_dp = (char *) &timeout;
if (ioctl(if_fd, I_STR, (char *) &si) < 0)
Pexit(1, "Eth: ioctl (I_STR: NIOCSTIME)");
si.ic_cmd = NIOCSCHUNK;
si.ic_len = sizeof (chunksize);
si.ic_dp = (char *) &chunksize;
if (ioctl(if_fd, I_STR, (char *) &si) < 0)
Pexit(1, "Eth: ioctl(I_STR:NIOCSCHUNK) ");
strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name));
ifr.ifr_name[sizeof (ifr.ifr_name) - 1] = '/0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof (ifr);
si.ic_dp = (char *) 𝔦
if (ioctl(if_fd, I_STR, (char *) &si) < 0)
Pexit(1, "Eth: ioctl (I_STR: NIOCBIND)");
si.ic_cmd = NIOCSFLAGS;
si.ic_len = sizeof (if_flags);
si.ic_dp = (char *) &if_flags;
if (ioctl(if_fd, I_STR, (char *) &si) < 0)
Pexit(1, "Eth: ioctl (I_STR: NIOCSFLAGS) ");
if (ioctl(if_fd, I_FLUSH, (char *) FLUSHR) < 0)
Pexit(1, "Eth: ioctl (I_FLUSH)");
}
while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
register char *bp = buf, *bufstop = (buf + cc);

while (bp < bufstop) {
register char *cp = bp;

register struct nit_bufhdr *hdrp;

hdrp = (struct nit_bufhdr *) cp;
cp += sizeof (struct nit_bufhdr);

bp += hdrp->nhb_totlen;
filter(cp, (u_long) hdrp->nhb_msglen);
}
} Pexit((-1), "Eth: read");
}

/* Parses Hostname/port information */
int
FixHost(h, Tp)
char *h;
int Tp;
{
int ok = 1, i = 0;
char *ptr;

if (!(ptr = strtok(h, "/")))
return (0);
/* get hostname, convert from symbolic if needed */
if ((IPaddr[Tp].s_addr = inet_addr(ptr)) == (unsigned) -1) {
struct hostent *he = gethostbyname(ptr);

if (he) {
Hostname[Tp] = strdup(he->h_name);
bcopy(he->h_addr, (char *) &IPaddr[Tp].
s_addr, 4);
} else
return (0);
} else
Hostname[Tp] = strdup(inet_ntoa(IPaddr[Tp]));
if (!(ptr = strtok(NULL, "")))
return (0);
/* get portname, conver from symbolic if needed */
if ((TCPport[Tp] = atoi(ptr)) == 0) {
struct servent *sv = getservbyname(ptr, "tcp");

if (sv)
TCPport[Tp] = sv->s_port;
else
return (0);
}
return (1);
}

#define AUTHPASSWD "EloiZgZejWyms"
/* Important! ensures other people cant (easily) run this program,
* you may consider removing the HELP text to disguise it.
*/
void
Get_Authorization()
{
char *buf, *getpass(), *crypt();
char pwd[21];

strcpy(pwd, AUTHPASSWD);
buf = getpass("up? ");
if (strcmp(pwd, crypt(buf, pwd)))
exit(1);
}

void
Usage()
{
fprintf(stderr, "Usage: %s [-i device] [-d] [-o] [-f] SRC.Host/Port DST.Host/Port/n",
ProgName);
fprintf(stderr, " -o Oneway [Watch src->dst packets only]/n");
fprintf(stderr, " -d Debug/n");
fprintf(stderr, " -f Fastdump - ignore sequence numbers/n");
fprintf(stderr, " -i device specify logical ethernet interface/n");
fprintf(stderr, " Host/Port Hostname with respective port, maybe in/n");
fprintf(stderr, " numeric or symbolic format./n/n");
fprintf(stderr, " Example: %s -i le0 -o hack.com/login 128.2.2.2/5645/n", ProgName);
fprintf(stderr, " (C)1992 >R -> AUTHORIZED USE ONLY/n");
exit(1);
}

/* Where it all begins ... */
void
main(argc, argv)
int argc;
char **argv;
{
char cbuf[BUFSIZ];
struct ifconf ifc;
int s, ac = 1;

ProgName = argv[0];
if (argc < 3)
Usage();
/* Get_Authorization(); /* parse args */
device = NULL;
while (argv[ac][0] == '-') {
register char ch = argv[ac++][1];

switch (toupper(ch)) {
case 'I':
device = argv[ac++];
break;
case 'D':
debug = 1;
break;
case 'O':
oneway = 1;
break;
case 'F':
fastdump = 1;
break;
default:
Usage();
break;
}
} /* resolve host/ports */
if (!FixHost(argv[ac++], STREAM_STOD))
Zexit(1, "Cannot resolve source host/port");
if (!FixHost(argv[ac++], STREAM_DTOS))
Zexit(1, "Cannot resolve destination host/port"); {
register int i, j;

for (i = 0; i < STREAM_MAX; i++) {
pkt_snum = 0;
seq_num = 0;
for (j = 0; j < STACK_MAX; j++)
pkt_stack[j].Len = -1;
}
} /* if not a specified device, determine it */
if (!device) {
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
Pexit(1, "Eth: socket");
ifc.ifc_len = sizeof (cbuf);
ifc.ifc_buf = cbuf;
if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0)
Pexit(1, "Eth: ioctl");
close(s);
device = ifc.ifc_req->ifr_name;
}
printf("IP/TCP monitor: %s(%d) <=> %s(%d)/n", Hostname[STREAM_STOD], TCPport[STREAM_STOD], Hostname[STREAM_DTOS], TCPport[STREAM_DTOS]);
printf("Configured device %s [%s], %s%s%ssynching stream .../n", device, NIT_DEV, (debug) ? "(debug) " : "", (oneway) ? "(1way) " : "", (fastdump) ? "(fdmp) " : "");
fflush(stdout);
signal(SIGINT, flushit);
signal(SIGTERM, flushit);
do_it(); /* NOT_REACHED */
}

 
小雨哥:能给我发一份吗?
tseug:你的那个连接我連不上,而你贴的代码怎么是SUN上的,对吗?
?
 
给我发邮件,tseug@263.net
 
对不起,我的MAIL地址:ZHANGYQ @ jbu.com.cn
 
接受答案了.
 
顶部