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

📄 tcp_input.pc

📁 无线自组织网络的一个协议仿真软件
💻 PC
📖 第 1 页 / 共 4 页
字号:
/* * GloMoSim is COPYRIGHTED software.  Release 2.02 of GloMoSim is available  * at no cost to educational users only. * * Commercial use of this software requires a separate license.  No cost, * evaluation licenses are available for such purposes; please contact * info@scalable-networks.com * * By obtaining copies of this and any other files that comprise GloMoSim2.02, * you, the Licensee, agree to abide by the following conditions and * understandings with respect to the copyrighted software: * * 1.Permission to use, copy, and modify this software and its documentation *   for education and non-commercial research purposes only is hereby granted *   to Licensee, provided that the copyright notice, the original author's *   names and unit identification, and this permission notice appear on all *   such copies, and that no charge be made for such copies. Any entity *   desiring permission to use this software for any commercial or *   non-educational research purposes should contact:  * *   Professor Rajive Bagrodia  *   University of California, Los Angeles  *   Department of Computer Science  *   Box 951596  *   3532 Boelter Hall  *   Los Angeles, CA 90095-1596  *   rajive@cs.ucla.edu * * 2.NO REPRESENTATIONS ARE MADE ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY *   PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * * 3.Neither the software developers, the Parallel Computing Lab, UCLA, or any *   affiliate of the UC system shall be liable for any damages suffered by *   Licensee from the use of this software. */// Use the latest version of Parsec if this line causes a compiler error./* * $Id: tcp_input.pc,v 1.12 2001/02/16 04:17:42 jmartin Exp $ * * Ported from FreeBSD 2.2.2. * This file contains TCP input routine, follows pages 65-76 of RFC 793. *//* * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995 *  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 the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *  This product includes software developed by the University of *  California, Berkeley and its contributors. * 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *  @(#)tcp_input.c 8.12 (Berkeley) 5/24/95 *  $Id: tcp_input.pc,v 1.12 2001/02/16 04:17:42 jmartin Exp $ */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "api.h"#include "main.h"#include "structmsg.h"#include "tcp.h"#include "transport.h"#include "in_pcb.h"#include "ip.h"#include "tcpip.h"#include "tcp_config.h"#include "tcp_hdr.h"#include "tcp_fsm.h"#include "tcp_proto.h"#include "tcp_seq.h"#include "tcp_timer.h"#include "tcp_var.h"static void data_adj(struct tcpiphdr *, int);static void submit_data(GlomoNode *, APP_TYPE, int,                         unsigned char *, int, struct tcpcb *);static void tcp_dooptions(struct tcpcb *, unsigned char *, int,                          struct tcpiphdr *, struct tcpopt *, unsigned long,                          struct tcpstat *); static void tcp_mss( struct tcpcb *, int, struct tcpstat * );static int tcp_reass(GlomoNode *, struct tcpcb *, struct tcpiphdr *,                     struct tcpstat *); static void tcp_xmit_timer(struct tcpcb *, int, struct tcpstat * ); staticvoid TransportTcpSetTimerForOutput(GlomoNode *node){    char clockStr[GLOMO_MAX_STRING_LENGTH];    Message *newMsg;    newMsg = GLOMO_MsgAlloc(node, GLOMO_TRANSPORT_LAYER, TRANSPORT_PROTOCOL_TCP,                            MSG_TRANSPORT_Tcp_CheckTcpOutputTimer);    GLOMO_MsgSend(node, newMsg, 0);}/* * Remove len bytes of data from a tcp segment. */static void data_adj(ti, len)    struct tcpiphdr *ti;    int len;{    unsigned char *old_start, *new_start;        if (len < ti->ti_len){        old_start = (unsigned char *) (ti + 1) ;        new_start = old_start + len;        memcpy(old_start, new_start, ti->ti_len - len);    }}/* * Reassemble received packets. * Deliver data to application if in sequence. */static inttcp_reass(node, tp, ti, tcp_stat)    GlomoNode *node;    struct tcpcb *tp;    struct tcpiphdr *ti;    struct tcpstat *tcp_stat;{    struct tcpiphdr *q, *ti1, *q1;    int flags;    struct inpcb *inp = tp->t_inpcb;    /*     * Call with ti==0 after become established to     * force pre-ESTABLISHED data up to user     */    if (ti == 0)        goto present;    /*     * Find a segment which begins after this one does.     */    for (q = tp->seg_next; q != (struct tcpiphdr *)tp;        q = (struct tcpiphdr *)q->ti_next)        if (SEQ_GT(q->ti_seq, ti->ti_seq))            break;    /*     * If there is a preceding segment, it may provide some of     * our data already.  If so, drop the data from the incoming     * segment.  If it provides all of our data, drop us.     */    if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {        int i;        q = (struct tcpiphdr *)q->ti_prev;        /* conversion to int (in i) handles seq wraparound */        i = q->ti_seq + q->ti_len - ti->ti_seq;        if (i > 0) {            if (i >= ti->ti_len) {                if (tcp_stat) {                    tcp_stat->tcps_rcvduppack++;                    tcp_stat->tcps_rcvdupbyte += ti->ti_len;                }                /*                 * Try to present any queued data                 * at the left window edge to the user.                 * This is needed after the 3-WHS                 * completes.                 */                pc_free(ti);                goto present;               }            data_adj(ti, i);            ti->ti_len -= i;            ti->ti_seq += i;        }        q = (struct tcpiphdr *)(q->ti_next);    }    if (tcp_stat) {        tcp_stat->tcps_rcvoopack++;        tcp_stat->tcps_rcvoobyte += ti->ti_len;    }    /*     * While we overlap succeeding segments trim them or,     * if they are completely covered, dequeue them.     */    while (q != (struct tcpiphdr *)tp) {        int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;        if (i <= 0)            break;        if (i < q->ti_len) {            data_adj(q, i);            q->ti_len -= i;            q->ti_seq += i;            break;        }        q1 = q;        q = (struct tcpiphdr *)q->ti_next;        remque_ti((struct tcpiphdr *)q->ti_prev);        pc_free(q1);    }    /*     * Stick new segment in its place.     */    insque_ti(ti, (struct tcpiphdr *)q->ti_prev);present:    /*     * Present data to user, advancing rcv_nxt through     * completed sequence space.     */    if (!TCPS_HAVEESTABLISHED(tp->t_state))        return (0);    ti = tp->seg_next;    if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)        return (0);    do {        tp->rcv_nxt += ti->ti_len;        flags = ti->ti_flags & TH_FIN;        remque_ti(ti);        submit_data(node, inp->app_proto_type, inp->con_id,                     (unsigned char *)(ti + 1), ti->ti_len, tp);         ti1 = ti;        ti = (struct tcpiphdr *)ti->ti_next;        pc_free(ti1);    } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);    return (flags);}/* * TCP input routine, follows pages 65-76 of the * protocol specification dated September, 1981 very closely. */voidtcp_input(node, payload, total_len, priority, p_head,           tcp_iss, tcp_now, tcp_stat)    GlomoNode *node;    unsigned char *payload;    int total_len;    int priority;    struct inpcb *p_head;    tcp_seq *tcp_iss;    unsigned long tcp_now;    struct tcpstat *tcp_stat;{    struct tcpiphdr *ti;    struct inpcb *inp;    struct tcpcb *tp = NULL;    unsigned char *tcp_seg;    const int tcprexmtthresh = 3;    unsigned char *optp = NULL;    unsigned char *datap = NULL;    int optlen = 0;    int len, tlen, off;    int tiflags;    int todrop, acked, ourfinisacked, needoutput = 0;    int iss = 0;    struct tcpopt topt;    unsigned long tiwin;    int to_accept = 0;     int flag;    tcp_seg   = (unsigned char *)pc_malloc(total_len);    assert(tcp_seg != NULL);    memcpy (tcp_seg, payload, total_len);    memset((char *)&topt, 0, sizeof(topt));    if (tcp_stat)        tcp_stat->tcps_rcvtotal++;    /*     * Get IP and TCP header together. Assume ip options has been striped.     * Note: IP leaves IP header in tcp_seg.     *      */    ti = (struct tcpiphdr *)tcp_seg;    if (total_len < sizeof (struct tcpiphdr)) {        if (tcp_stat)            tcp_stat->tcps_rcvshort++;        pc_free(tcp_seg);           return;    }    /*     * Checksum extended TCP header and data.     * Note here assumes ip hasn't subtracted ip header      * length from ip_len (different from original code).     * Assuming here that the source and destination IP address     * fields and the packet length field have been correctly     * set.     */        len = ti->ti_len;    tlen = len - sizeof(struct ipovly);    ti->ti_len = tlen;        /*      * Zero and set this stuff in the "Extended pseudoheader"     * for the checksum      */    ti->ti_prev = 0;    ti->ti_next = 0;    ti->ti_x1 = 0;    ti->ti_pr = IPPROTO_TCP;                   ti->ti_sum = in_cksum( (unsigned short *) tcp_seg, len);    if (ti->ti_sum) {        if (tcp_stat)            tcp_stat->tcps_rcvbadsum++;        goto drop;    }    /*     * Check that TCP offset makes sense,     * pull out TCP options and adjust length.      XXX     */    off = ti->ti_off << 2;    if (off < sizeof (struct tcphdr) || off > tlen) {        if (tcp_stat)            tcp_stat->tcps_rcvbadoff++;        goto drop;    }    tlen -= off;  /* data length */    ti->ti_len = tlen;    optlen = off - sizeof (struct tcphdr);    optp = tcp_seg + sizeof(struct tcpiphdr);    datap = optp + optlen;    tiflags = ti->ti_flags;    if (tcp_stat) {        if (tlen > 0){             tcp_stat->tcps_rcvpack ++;            tcp_stat->tcps_rcvbyte += ti->ti_len;        }        else if (tiflags & (TH_SYN|TH_FIN|TH_RST))            tcp_stat->tcps_rcvctrl ++;    }    /*     * Locate pcb for segment.     */findpcb:                         inp = in_pcblookup(p_head, ti->ti_dst, ti->ti_dport,                       ti->ti_src, ti->ti_sport, INPCB_NO_WILDCARD);    /*     * PCB doesn't exist, check if it's a connection request.      * If so, prepare to accept the connection.  Otherwise, drop      * the packet.      */    if (inp == p_head){        inp = in_pcblookup(p_head, ti->ti_dst, ti->ti_dport,                           ti->ti_src, ti->ti_sport, INPCB_WILDCARD);        if (inp != p_head)             to_accept = 1;                    else            goto dropwithreset;    }            tp = intotcpcb(inp);    if (tp->t_state == TCPS_CLOSED)        goto drop;            /* Unscale the window into a 32-bit value. */    if ((tiflags & TH_SYN) == 0)        tiwin = ti->ti_win << tp->snd_scale;    else        tiwin = ti->ti_win;    if (to_accept) {        to_accept = 0;        if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {            /*             * Note: dropwithreset makes sure we don't             * send a RST in response to a RST.             */            if (tiflags & TH_ACK) {                if (tcp_stat)                    tcp_stat->tcps_badsyn++;                goto dropwithreset;            }            goto drop;        }        inp = (struct inpcb *)tcp_attach(p_head, inp->app_proto_type,                                          ti->ti_dst,  ti->ti_dport,                                          ti->ti_src, ti->ti_sport,                                         -1, priority);                                                if (inp == 0) {            goto drop;        }        tp = intotcpcb(inp);                                 tp->t_state = TCPS_LISTEN;        /* Compute proper scaling value from buffer space */        while (tp->request_r_scale < TCP_MAX_WINSHIFT &&           TCP_MAXWIN << tp->request_r_scale < inp->inp_rcv_hiwat)            tp->request_r_scale++;    }    /*     * Segment received on connection.     * Reset idle time and keep-alive timer.     */    tp->t_idle = 0;    if (TCPS_HAVEESTABLISHED(tp->t_state))

⌨️ 快捷键说明

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