亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tcp.c

?? Redboot 源碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
//==========================================================================
//
//      net/tcp.c
//
//      Stand-alone TCP networking support for RedBoot
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos 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 or (at your option) any later version.
//
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    gthomas
// Contributors: gthomas
// Date:         2000-07-14
// Purpose:      
// Description:  
//              
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
//
//==========================================================================

#include <net/net.h>

#define MAX_TCP_SEGMENT (ETH_MAX_PKTLEN - (sizeof(eth_header_t) + sizeof(ip_header_t)))
#define MAX_TCP_DATA    (MAX_TCP_SEGMENT - sizeof(tcp_header_t))


/* sequence number comparison macros */
#define SEQ_LT(a,b) ((int)((a)-(b)) < 0)
#define SEQ_LE(a,b) ((int)((a)-(b)) <= 0)
#define SEQ_GT(a,b) ((int)((a)-(b)) > 0)
#define SEQ_GE(a,b) ((int)((a)-(b)) >= 0)

/* Set a timer which will send an RST and abort a connection. */
static timer_t abort_timer;

static void do_retrans(void *p);
static void do_close(void *p);

#ifdef BSP_LOG
static char *
flags_to_str(octet f)
{
    static char str[7], *p;

    p = str;

    if (f & TCP_FLAG_FIN)
	*p++ = 'F';
    if (f & TCP_FLAG_SYN)
	*p++ = 'S';
    if (f & TCP_FLAG_RST)
	*p++ = 'R';
    if (f & TCP_FLAG_PSH)
	*p++ = 'P';
    if (f & TCP_FLAG_ACK)
	*p++ = 'A';
    if (f & TCP_FLAG_URG)
	*p++ = 'U';
    *p = '\0';
    return str;
}
#endif

/*
 * A major assumption is that only a very small number of sockets will
 * active, so a simple linear search of those sockets is acceptible.
 */
static tcp_socket_t *tcp_list;

/*
 * Format and send an outgoing segment.
 */
static void
tcp_send(tcp_socket_t *s, int flags, int resend)
{
    tcp_header_t *tcp;
    ip_header_t  *ip;
    pktbuf_t     *pkt = &s->pkt;
    unsigned short cksum;
    dword         tcp_magic;
    int           tcp_magic_size = sizeof(tcp_magic);

    ip = pkt->ip_hdr;
    tcp = pkt->tcp_hdr;

    if (flags & TCP_FLAG_SYN) {
	/* If SYN, assume no data and send MSS option in tcp header */
	pkt->pkt_bytes = sizeof(tcp_header_t) + 4;
	tcp->hdr_len = 6;
        tcp_magic = htonl(0x02040000 | MAX_TCP_DATA);
	memcpy((unsigned char *)(tcp+1), &tcp_magic, tcp_magic_size);
	s->data_bytes = 0;
    } else {
	pkt->pkt_bytes = s->data_bytes + sizeof(tcp_header_t);
	tcp->hdr_len = 5;
    }

    /* tcp header */
    tcp->reserved = 0;
    tcp->seqnum = htonl(s->seq);
    tcp->acknum = htonl(s->ack);
    tcp->checksum = 0;

    if (!resend) {
	tcp->src_port = htons(s->our_port);
	tcp->dest_port = htons(s->his_port);
	tcp->flags = flags;
	/* always set PUSH flag if sending data */
	if (s->data_bytes)
	    tcp->flags |= TCP_FLAG_PSH;
	tcp->window = htons(MAX_TCP_DATA);
	tcp->urgent = 0;

	/* fill in some pseudo-header fields */
	memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t));
	memcpy(ip->destination, s->his_addr.ip_addr, sizeof(ip_addr_t));
	ip->protocol = IP_PROTO_TCP;
    }

    /* another pseudo-header field */
    ip->length = htons(pkt->pkt_bytes);

    /* compute tcp checksum */
    cksum = __sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip));
    tcp->checksum = htons(cksum);

    __ip_send(pkt, IP_PROTO_TCP, &s->his_addr);

    BSPLOG(bsp_log("tcp_send: state[%d] flags[%s] ack[%x] data[%d].\n",
		   s->state, flags_to_str(tcp->flags), s->ack, s->data_bytes));

    if (s->state == _TIME_WAIT) {
        // If 'reuse' is set on socket, close after 1 second, otherwise 2 minutes
        __timer_set(&s->timer, s->reuse ? 1000 : 120000, do_close, s);
    }
    else if ((tcp->flags & (TCP_FLAG_FIN | TCP_FLAG_SYN)) || s->data_bytes)
	__timer_set(&s->timer, 1000, do_retrans, s);
}

static pktbuf_t ack_pkt;
static word     ack_buf[ETH_MIN_PKTLEN/sizeof(word)];

/*
 * Send an ack.
 */
static void
send_ack(tcp_socket_t *s)
{
    tcp_header_t *tcp;
    ip_header_t  *ip;
    unsigned short cksum;

    ack_pkt.buf = ack_buf;
    ack_pkt.bufsize = sizeof(ack_buf);
    ack_pkt.ip_hdr = ip = (ip_header_t *)ack_buf;
    ack_pkt.tcp_hdr = tcp = (tcp_header_t *)(ip + 1);
    ack_pkt.pkt_bytes = sizeof(tcp_header_t);

    /* tcp header */
    tcp->hdr_len = 5;
    tcp->reserved = 0;
    tcp->seqnum = htonl(s->seq);
    tcp->acknum = htonl(s->ack);
    tcp->checksum = 0;

    tcp->src_port = htons(s->our_port);
    tcp->dest_port = htons(s->his_port);
    tcp->flags = TCP_FLAG_ACK;

    tcp->window = htons(MAX_TCP_DATA);
    tcp->urgent = 0;

    /* fill in some pseudo-header fields */
    memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t));
    memcpy(ip->destination, s->his_addr.ip_addr, sizeof(ip_addr_t));
    ip->protocol = IP_PROTO_TCP;

    /* another pseudo-header field */
    ip->length = htons(sizeof(tcp_header_t));

    /* compute tcp checksum */
    cksum = __sum((word *)tcp, sizeof(*tcp), __pseudo_sum(ip));
    tcp->checksum = htons(cksum);

    __ip_send(&ack_pkt, IP_PROTO_TCP, &s->his_addr);
}


/*
 * Send a reset for a bogus incoming segment.
 */
static void
send_reset(pktbuf_t *pkt, ip_route_t *r)
{
    ip_header_t   *ip = pkt->ip_hdr;
    tcp_header_t  *tcp = pkt->tcp_hdr;
    dword         seq, ack;
    word          src, dest;
    word          cksum;

    seq = ntohl(tcp->acknum);
    ack = ntohl(tcp->seqnum);
    src = ntohs(tcp->dest_port);
    dest = ntohs(tcp->src_port);

    tcp = (tcp_header_t *)(ip + 1);
    pkt->pkt_bytes = sizeof(tcp_header_t);
    
    /* tcp header */
    tcp->hdr_len = 5;
    tcp->reserved = 0;
    tcp->seqnum = htonl(seq);
    tcp->acknum = htonl(ack);
    tcp->window = htons(1024);
    tcp->urgent = 0;
    tcp->checksum = 0;
    tcp->src_port = htons(src);
    tcp->dest_port = htons(dest);
    tcp->flags = TCP_FLAG_RST | TCP_FLAG_ACK;

    /* fill in some pseudo-header fields */
    memcpy(ip->source, __local_ip_addr, sizeof(ip_addr_t));
    memcpy(ip->destination, r->ip_addr, sizeof(ip_addr_t));
    ip->protocol = IP_PROTO_TCP;
    ip->length = htons(pkt->pkt_bytes);

    /* compute tcp checksum */
    cksum = __sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip));
    tcp->checksum = htons(cksum);

    __ip_send(pkt, IP_PROTO_TCP, r);
}



/*
 * Remove given socket from socket list.
 */
static void
unlink_socket(tcp_socket_t *s)
{
    tcp_socket_t *prev, *tp;

    for (prev = NULL, tp = tcp_list; tp; prev = tp, tp = tp->next)
	if (tp == s) {
	    BSPLOG(bsp_log("unlink tcp socket.\n"));
	    if (prev)
		prev->next = s->next;
	    else
		tcp_list = s->next;
	}
}

/*
 * Retransmit last packet.
 */
static void
do_retrans(void *p)
{
    BSPLOG(bsp_log("tcp do_retrans.\n"));
    tcp_send((tcp_socket_t *)p, 0, 1);
}


static void
do_close(void *p)
{
    BSPLOG(bsp_log("tcp do_close.\n"));
    /* close connection */
    ((tcp_socket_t *)p)->state = _CLOSED;
    unlink_socket(p);
}


static void
free_rxlist(tcp_socket_t *s)
{
    pktbuf_t *p;

    BSPLOG(bsp_log("tcp free_rxlist.\n"));

    while ((p = s->rxlist) != NULL) {
	s->rxlist = p->next;
	__pktbuf_free(p);
    }
}


/*
 * Handle a conection reset.
 */
static void
do_reset(tcp_socket_t *s)
{
    /* close connection */
    s->state = _CLOSED;
    __timer_cancel(&s->timer);
    free_rxlist(s);
    unlink_socket(s);
}


/*
 * Extract data from incoming tcp segment.
 * Returns true if packet is queued on rxlist, false otherwise.
 */
static int
handle_data(tcp_socket_t *s, pktbuf_t *pkt)
{
    tcp_header_t  *tcp = pkt->tcp_hdr;
    unsigned int  diff, seq;
    int           data_len;
    char          *data_ptr;
    pktbuf_t      *p;

    data_len = pkt->pkt_bytes - (tcp->hdr_len << 2);
    data_ptr = ((char *)tcp)  + (tcp->hdr_len << 2);

    seq = ntohl(tcp->seqnum);

    BSPLOG(bsp_log("tcp data: seq[%x] len[%d].\n", seq, data_len));

    if (SEQ_LE(seq, s->ack)) {
	/*
	 * Figure difference between which byte we're expecting and which byte
	 * is sent first. Adjust data length and data pointer accordingly.
	 */
	diff = s->ack - seq;
	data_len -= diff;
	data_ptr += diff;

	if (data_len > 0) {
	    /* queue the new data */
	    s->ack += data_len;
	    pkt->next = NULL;
	    if ((p = s->rxlist) != NULL) {
		while (p->next)
		    p = p->next;
		p->next = pkt;
		BSPLOG(bsp_log("tcp data: Add pkt[%x] len[%d].\n",
			       pkt, data_len));
	    } else {
		s->rxlist = pkt;
		s->rxcnt = data_len;
		s->rxptr = data_ptr;
		BSPLOG(bsp_log("tcp data: pkt[%x] len[%d].\n",
			       pkt, data_len));
	    }
	    return 1;
	}
    }
    return 0;
}


static void
handle_ack(tcp_socket_t *s, pktbuf_t *pkt)
{
    tcp_header_t *tcp = pkt->tcp_hdr;
    dword        ack;
    int          advance;
    char         *dp;

    /* process ack value in packet */
    ack = ntohl(tcp->acknum);

    BSPLOG(bsp_log("Rcvd tcp ACK %x\n", ack));

    if (SEQ_GT(ack, s->seq)) {
	__timer_cancel(&s->timer);
	advance = ack - s->seq;
	if (advance > s->data_bytes)
	    advance = s->data_bytes;

	BSPLOG(bsp_log("seq advance %d", advance));

	if (advance > 0) {
	    s->seq += advance;
	    s->data_bytes -= advance;
	    if (s->data_bytes) {
		/* other end ack'd only part of the pkt */
		BSPLOG(bsp_log(" %d bytes left", s->data_bytes));
		dp = (char *)(s->pkt.tcp_hdr + 1);
		memcpy(dp, dp + advance, s->data_bytes);
	    }
	}
    }
    BSPLOG(bsp_log("\n"));
}


/*
 * Handle incoming TCP packets.
 */
void
__tcp_handler(pktbuf_t *pkt, ip_route_t *r)
{
    tcp_header_t *tcp = pkt->tcp_hdr;
    ip_header_t  *ip = pkt->ip_hdr;
    tcp_socket_t *prev,*s;
    dword        ack;
    int          queued = 0;

    /* set length for pseudo sum calculation */
    ip->length = htons(pkt->pkt_bytes);

    if (__sum((word *)tcp, pkt->pkt_bytes, __pseudo_sum(ip)) == 0) {
	for (prev = NULL, s = tcp_list; s; prev = s, s = s->next) {
	    if (s->our_port == ntohs(tcp->dest_port)) {
		if (s->his_port == 0)
		    break;
		if (s->his_port == ntohs(tcp->src_port) &&
		    !memcmp(r->ip_addr, s->his_addr.ip_addr, sizeof(ip_addr_t)))
		    break;
	    }
	}

	if (s) {
	    /* found the socket this packet belongs to */
	    
	    /* refresh his ethernet address */
	    memcpy(s->his_addr.enet_addr, r->enet_addr, sizeof(enet_addr_t));

	    if (s->state != _SYN_RCVD && tcp->flags & TCP_FLAG_RST) {

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲激情综合网| 成人精品一区二区三区中文字幕| 午夜影视日本亚洲欧洲精品| 乱中年女人伦av一区二区| 成人app在线| 日韩欧美专区在线| 亚洲免费观看在线视频| 国产真实精品久久二三区| 色老综合老女人久久久| 国产校园另类小说区| 午夜一区二区三区视频| www.av亚洲| 久久免费视频色| 麻豆精品国产91久久久久久| 欧美在线视频不卡| 亚洲免费在线播放| 欧美成人乱码一区二区三区| 亚洲欧美日韩国产中文在线| 国产经典欧美精品| 精品成人佐山爱一区二区| 亚洲欧美韩国综合色| 粉嫩久久99精品久久久久久夜| 日韩美女视频在线| 蜜臀久久久久久久| 91精品国产综合久久精品app| 亚洲视频免费观看| 91免费精品国自产拍在线不卡| 久久精品亚洲乱码伦伦中文 | 秋霞av亚洲一区二区三| 日本乱人伦aⅴ精品| 日韩一区日韩二区| 色诱视频网站一区| 夜夜嗨av一区二区三区中文字幕 | 久久久九九九九| 国产一区久久久| 精品国产乱码久久久久久久久| 免费成人美女在线观看| 91精品国产综合久久香蕉的特点 | 丝袜美腿一区二区三区| 欧美色倩网站大全免费| 亚洲欧美国产三级| 欧美三级视频在线观看 | 综合色中文字幕| 91美女蜜桃在线| 亚洲一区二区三区四区五区中文| 日本电影亚洲天堂一区| 亚洲国产美国国产综合一区二区| 欧美日韩国产综合久久| 精品一区二区三区在线观看 | 激情另类小说区图片区视频区| 欧美成人福利视频| 处破女av一区二区| 一区二区三区鲁丝不卡| 欧美日韩高清在线| 国产在线精品免费| 中文字幕欧美一| 欧美精品 日韩| 国产精品一区2区| 亚洲人妖av一区二区| 欧美巨大另类极品videosbest | 欧美大度的电影原声| 国产一二精品视频| 一区二区三区四区av| 日韩免费电影网站| av成人动漫在线观看| 天堂蜜桃一区二区三区| 久久久久久久久免费| 在线视频中文字幕一区二区| 蜜臀久久99精品久久久久久9| 国产亚洲短视频| 欧美日韩一区二区三区视频| 久久国产精品无码网站| 亚洲免费观看在线视频| 精品剧情在线观看| 欧美在线|欧美| 国产成人在线看| 日韩电影网1区2区| 最新日韩av在线| 精品久久久久香蕉网| 在线精品亚洲一区二区不卡| 激情图区综合网| 亚洲18色成人| 中文字幕一区二区三区在线播放| 欧美一区二区三区视频在线| 99视频精品免费视频| 久久99精品久久久久| 亚洲亚洲人成综合网络| 亚洲成人av电影在线| 欧美国产乱子伦 | 色综合久久久久久久久| 精品一区二区三区在线观看| 亚洲精品视频在线| 国产精品免费观看视频| 精品99久久久久久| 在线综合+亚洲+欧美中文字幕| av亚洲精华国产精华精华| 国产一区欧美一区| 精品亚洲国内自在自线福利| 亚洲永久免费视频| 亚洲激情五月婷婷| 中文字幕一区二区三区不卡在线| 久久综合久久鬼色| 日韩一区二区三区av| 欧美另类变人与禽xxxxx| 一道本成人在线| 99精品黄色片免费大全| 粉嫩嫩av羞羞动漫久久久| 国产米奇在线777精品观看| 精品一区精品二区高清| 麻豆精品一区二区av白丝在线| 亚洲va欧美va人人爽| 一区二区三区美女| 亚洲一区中文日韩| 亚洲一区av在线| 亚洲国产精品人人做人人爽| 成人一区二区视频| 国产精品白丝jk白祙喷水网站| 久久国产精品72免费观看| 美女爽到高潮91| 久久99精品久久久久久动态图| 蜜桃视频一区二区| 精品一区二区三区久久久| 麻豆91在线观看| 国产麻豆9l精品三级站| 国产高清精品网站| 不卡在线观看av| 色噜噜狠狠成人中文综合| 欧美性一二三区| 69堂精品视频| 久久久久久毛片| 国产精品美女久久久久高潮| 亚洲免费观看高清完整版在线观看 | 色综合av在线| 在线观看网站黄不卡| 欧美日韩国产一级| 91精品国产入口| 久久婷婷色综合| 中文字幕在线不卡国产视频| 亚洲欧美一区二区三区国产精品 | 亚洲精品第一国产综合野| 亚洲综合小说图片| 日韩国产精品久久| 国内外成人在线| 99久久er热在这里只有精品15| jlzzjlzz国产精品久久| 91精品福利视频| 日韩欧美国产不卡| 亚洲国产精品二十页| 一区二区三区免费在线观看| 日韩精品欧美精品| 成人一道本在线| 在线成人免费观看| 国产婷婷一区二区| 亚洲小说欧美激情另类| 国产一区二区剧情av在线| aaa欧美日韩| 日韩一区二区视频在线观看| 国产精品国产三级国产a| 天天av天天翘天天综合网色鬼国产| 国产一区激情在线| 欧美在线啊v一区| 欧美激情综合网| 日韩精品视频网站| 色综合天天性综合| 久久蜜桃香蕉精品一区二区三区| 亚洲欧洲国产日韩| 精品一区免费av| 777久久久精品| 亚洲黄色尤物视频| 国产盗摄女厕一区二区三区| 欧美日韩亚洲国产综合| 国产精品久久久久久亚洲伦| 日本视频在线一区| 在线精品视频一区二区三四| 久久九九影视网| 久久精品国产免费看久久精品| 色综合久久久久网| 中文字幕中文字幕在线一区 | 欧美午夜一区二区三区 | 日韩女优电影在线观看| 亚洲乱码国产乱码精品精可以看 | 一区二区三区毛片| 成人国产电影网| 久久久久久夜精品精品免费| 午夜精品免费在线观看| 91福利在线播放| 综合在线观看色| 91在线观看免费视频| 中文字幕国产一区| 懂色av一区二区三区免费观看| 日韩免费高清av| 久久精品国产999大香线蕉| 3d动漫精品啪啪| 亚洲不卡av一区二区三区| 在线精品视频免费播放| 一区二区三区国产| 欧美亚洲综合久久| 亚洲国产另类精品专区| 欧美性大战久久久| 日日摸夜夜添夜夜添国产精品|