⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcppkt.c

📁 BCAST Implementation for NS2
💻 C
字号:
/* *   OSPFD routing daemon *   Copyright (C) 1998 by John T. Moy *    *   This program is free software; you can redistribute it and/or *   modify it under the terms of the GNU General Public License *   as published by the Free Software Foundation; either version 2 *   of the License, or (at your option) any later version. *    *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. *    *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include "ospf_module.h"#include "machdep.h"#include "tcppkt.h"/* Constructor for the packet-based TCP * processing. */TcpPkt::TcpPkt(int fdesc){    fd = fdesc;    blen = sizeof(TcpPktHdr);    rcvbuff = new byte[blen];    offset = 0;    xmt_done = 0;    xmt_head = 0;    xmt_tail = 0;}/* Destructor for the packet-based TCP * processing. */TcpPkt::~TcpPkt(){    delete [] rcvbuff;}/* Attempt to receive a packet. May have already received * a partial packet. New packet may be larger than current rcvbuff * requiring a new allocation. * If a full message is assembled, a pointer to its data is returned. * Otherwise returns NULL. */int TcpPkt::receive(void **fullmsg, uns16 &type, uns16 &subtype){   int target;	// Number of bytes to read this time    int nbytes;     TcpPktHdr *msg;    *fullmsg = 0;    type = 0;    subtype = 0;    msg = (TcpPktHdr *) rcvbuff;    // Get size of message that you are    // currently trying to reassemble    // Read header first    if (offset < (int) sizeof(TcpPktHdr))	target = sizeof(TcpPktHdr) - offset;    else {	int mlen;	mlen = ntoh16(msg->length);	target = mlen - offset;	if (mlen > blen) {	    byte *newbuf;	    newbuf = new byte[mlen];	    blen = mlen;	    memmove(newbuf, rcvbuff, offset);	    delete [] rcvbuff;	    rcvbuff = newbuf;	    msg = (TcpPktHdr *) rcvbuff;	}    }    if ((nbytes = recv(fd, rcvbuff+offset, target, 0)) <= 0)        return(-1);    // Update reassembly parameters    offset += nbytes;    // Valid version?    if (offset >= (int) sizeof(TcpPktHdr)) {        if (ntoh16(msg->version) != TCPPKT_VERS)	    return(-1);    }    // Completed reassembly?    if (offset >= (int) sizeof(TcpPktHdr) && offset == ntoh16(msg->length)) {	*fullmsg = msg+1;	type = ntoh16(msg->type);	subtype = ntoh16(msg->subtype);	// Reset rcvbuff parameters	offset = 0;	return(ntoh16(msg->length) - sizeof(TcpPktHdr));    }    // Message still in progress    return(0);}	/* Wait until an entire monitoring response has * been received. */int TcpPkt::rcv_suspend(void **mp, uns16 &type, uns16 &subtype){    int n_bytes;    do {	n_bytes = receive(mp, type, subtype);	if (n_bytes == -1) {	    perror("recv");	    exit(1);	}    } while (type == 0);    return(n_bytes);}/* Queue a packet for transmission. * Immediately copy the packet into a local buffer * that will be sent later. */void TcpPkt::queue_xpkt(void *msg, uns16 type, uns16 subtype, int len){    PktList *newpkt;    newpkt = new PktList;    newpkt->next = 0;    newpkt->hdr.version = hton16(TCPPKT_VERS);    newpkt->hdr.type = hton16(type);    newpkt->hdr.subtype = hton16(subtype);    if (len) {	newpkt->body = new byte[len];	memcpy(newpkt->body, msg, len);    }    else	newpkt->body = 0;    // Count header in length    newpkt->hdr.length = hton16(len + sizeof(TcpPktHdr));    if (xmt_head == 0)        xmt_head = xmt_tail = newpkt;    else {        xmt_tail->next = newpkt;	xmt_tail = newpkt;    }}/* Send all or part of the "head" packet onto the * TCP stream. */bool TcpPkt::sendpkt(){    PktList *pkt;    byte *data;    int to_send;    int n_sent;    bool sending_body;    if (!(pkt = xmt_head))	return(true);    n_sent = 0;    if (xmt_done < (int) sizeof(TcpPktHdr)) {	to_send = sizeof(TcpPktHdr) - xmt_done;	data = ((byte *) &pkt->hdr) + xmt_done;	sending_body = false;    }    else {        to_send = ntoh16(pkt->hdr.length) - xmt_done;	data = pkt->body - (xmt_done - sizeof(TcpPktHdr));	sending_body = true;    }    if (to_send > 0 && (n_sent = send(fd, data, to_send, 0)) == -1)	return(false);    // Done with current packet?    if (sending_body && n_sent == to_send) {        xmt_head = pkt->next;	if (!xmt_head)	    xmt_tail = 0;	xmt_done = 0;	delete [] pkt->body;	delete pkt;    }    else        xmt_done += n_sent;    return(true);}/* Block sending a given packet onto the TCP stream. * Returns an error if we are in the middle of sending * another packet. */bool TcpPkt::sendpkt_suspend(void *msg, uns16 type,			     uns16 subtype, int len){    TcpPktHdr hdr;    int i;    int n_sent;    byte *data;    if (xmt_done != 0)	return(false);    hdr.version = hton16(TCPPKT_VERS);    hdr.type = hton16(type);    hdr.subtype = hton16(subtype);    hdr.length = hton16(len + sizeof(hdr));    // First send header    for (i = 0; i < (int) sizeof(hdr); i += n_sent) {        data = ((byte *) &hdr) + i;	n_sent = send(fd, data, sizeof(hdr) - i, 0);	if (n_sent == -1)	    return(false);    }    // Then send body    for (i = 0; i < len; i += n_sent) {        data = ((byte *) msg) + i;	n_sent = send(fd, data, len - i, 0);	if (n_sent == -1)	    return(false);    }    return(true);}/* Indicate whether there is data ready to send on * the TCP connection. */bool TcpPkt::xmt_pending(){    return(xmt_head != 0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -