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

📄 dn_nsp_out.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}}int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum){	struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;	struct dn_scp *scp = &sk->protinfo.dn;	struct sk_buff *skb2, *list, *ack = NULL;	int wakeup = 0;	unsigned long reftime = cb->stamp;	unsigned long pkttime;	unsigned short xmit_count;	unsigned short segnum;	skb2 = q->next;	list = (struct sk_buff *)q;	while(list != skb2) {		struct dn_skb_cb *cb2 = (struct dn_skb_cb *)skb2->cb;		if (before_or_equal(cb2->segnum, acknum))			ack = skb2;		/* printk(KERN_DEBUG "ack: %s %04x %04x\n", ack ? "ACK" : "SKIP", (int)cb2->segnum, (int)acknum); */		skb2 = skb2->next;		if (ack == NULL)			continue;		/* printk(KERN_DEBUG "check_xmit_queue: %04x, %d\n", acknum, cb2->xmit_count); */		wakeup = 1;		pkttime = cb2->stamp;		xmit_count = cb2->xmit_count;		segnum = cb2->segnum;		skb_unlink(ack);		kfree_skb(ack);		ack = NULL;		if (xmit_count == 1) {			if (equal(segnum, acknum)) 				dn_nsp_rtt(sk, (long)(pkttime - reftime));			if (scp->snd_window < NSP_MAX_WINDOW)				scp->snd_window++;		}	}#if 0 /* Turned off due to possible interference in socket shutdown */	if ((skb_queue_len(&scp->data_xmit_queue) == 0) &&	    (skb_queue_len(&scp->other_xmit_queue) == 0))		scp->persist = 0;#endif	return wakeup;}void dn_nsp_send_data_ack(struct sock *sk){	struct sk_buff *skb = NULL;	struct  nsp_data_ack_msg *msg;	if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL)		return;		msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg));	msg->msgflg  = 0x04;			/* data ack message	*/	msg->dstaddr = sk->protinfo.dn.addrrem;	msg->srcaddr = sk->protinfo.dn.addrloc;	msg->acknum  = dn_htons((sk->protinfo.dn.numdat_rcv & 0x0FFF) | 0x8000);	sk->protinfo.dn.ackxmt_dat = sk->protinfo.dn.numdat_rcv;	dn_nsp_send(skb);}void dn_nsp_send_oth_ack(struct sock *sk){	struct sk_buff *skb = NULL;	struct  nsp_data_ack_msg *msg;	if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL)		return;		msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg));	msg->msgflg = 0x14;	/* oth ack message	*/	msg->dstaddr = sk->protinfo.dn.addrrem;	msg->srcaddr = sk->protinfo.dn.addrloc;	msg->acknum  = dn_htons((sk->protinfo.dn.numoth_rcv & 0x0FFF) | 0x8000);	sk->protinfo.dn.ackxmt_oth = sk->protinfo.dn.numoth_rcv;	dn_nsp_send(skb);}void dn_send_conn_ack (struct sock *sk){	struct dn_scp *scp = &sk->protinfo.dn;	struct sk_buff *skb = NULL;        struct nsp_conn_ack_msg *msg;	if ((skb = dn_alloc_skb(sk, 3, sk->allocation)) == NULL)		return;        msg = (struct nsp_conn_ack_msg *)skb_put(skb, 3);        msg->msgflg = 0x24;                   	msg->dstaddr = scp->addrrem;	dn_nsp_send(skb);	}void dn_nsp_delayed_ack(struct sock *sk){	struct dn_scp *scp = &sk->protinfo.dn;	if (scp->ackxmt_oth != scp->numoth_rcv)		dn_nsp_send_oth_ack(sk);	if (scp->ackxmt_dat != scp->numdat_rcv)		dn_nsp_send_data_ack(sk);}static int dn_nsp_retrans_conn_conf(struct sock *sk){	struct dn_scp *scp = &sk->protinfo.dn;	if (scp->state == DN_CC)		dn_send_conn_conf(sk, GFP_ATOMIC);	return 0;}void dn_send_conn_conf(struct sock *sk, int gfp){	struct dn_scp *scp = &sk->protinfo.dn;	struct sk_buff *skb = NULL;        struct nsp_conn_init_msg *msg;	unsigned char len = scp->conndata_out.opt_optl;	if ((skb = dn_alloc_skb(sk, 50 + scp->conndata_out.opt_optl, gfp)) == NULL)		return;        msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg));        msg->msgflg = 0x28;                   	msg->dstaddr = scp->addrrem;        msg->srcaddr = scp->addrloc;        msg->services = 0x01;        msg->info = 0x03;        msg->segsize = dn_htons(0x05B3);	*skb_put(skb,1) = len;	if (len > 0) 		memcpy(skb_put(skb, len), scp->conndata_out.opt_data, len);		dn_nsp_send(skb);	scp->persist = dn_nsp_persist(sk);	scp->persist_fxn = dn_nsp_retrans_conn_conf;}static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, 			unsigned short reason, int gfp, struct dst_entry *dst,			int ddl, unsigned char *dd, __u16 rem, __u16 loc){	struct sk_buff *skb = NULL;	int size = 7 + ddl + ((msgflg == NSP_DISCINIT) ? 1 : 0);	unsigned char *msg;	if ((dst == NULL) || (rem == 0)) {		if (net_ratelimit())			printk(KERN_DEBUG "DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", (unsigned)rem, dst);		return;	}	if ((skb = dn_alloc_skb(sk, size, gfp)) == NULL)		return;	msg = skb_put(skb, size);	*msg++ = msgflg;	*(__u16 *)msg = rem;	msg += 2;	*(__u16 *)msg = loc;	msg += 2;	*(__u16 *)msg = dn_htons(reason);	msg += 2;	if (msgflg == NSP_DISCINIT)		*msg++ = ddl;	if (ddl) {		memcpy(msg, dd, ddl);	}	/*	 * This doesn't go via the dn_nsp_send() fucntion since we need	 * to be able to send disc packets out which have no socket	 * associations.	 */	skb->dst = dst_clone(dst);	skb->dst->output(skb);}void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg, 			unsigned short reason, int gfp){	struct dn_scp *scp = &sk->protinfo.dn;	int ddl = 0;	if (msgflg == NSP_DISCINIT)		ddl = scp->discdata_out.opt_optl;	if (reason == 0)		reason = scp->discdata_out.opt_status;	dn_nsp_do_disc(sk, msgflg, reason, gfp, sk->dst_cache, ddl, 		scp->discdata_out.opt_data, scp->addrrem, scp->addrloc);}void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg, 			unsigned short reason){	struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;	int ddl = 0;	int gfp = GFP_ATOMIC;	dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb->dst, ddl, 			NULL, cb->src_port, cb->dst_port);}void dn_nsp_send_lnk(struct sock *sk, unsigned short flgs){	struct dn_scp *scp = &sk->protinfo.dn;	struct sk_buff *skb = NULL;	struct nsp_data_seg_msg	*msg;	struct nsp_data_opt_msg	*msg1;	struct dn_skb_cb *cb;	if ((skb = dn_alloc_skb(sk, 80, GFP_ATOMIC)) == NULL)		return;	cb = (struct dn_skb_cb *)skb->cb;		msg = (struct nsp_data_seg_msg *)skb_put(skb, sizeof(*msg));	msg->msgflg = 0x10;			/* Link svc message	*/	msg->dstaddr = scp->addrrem;	msg->srcaddr = scp->addrloc;	msg1 = (struct nsp_data_opt_msg *)skb_put(skb, sizeof(*msg1));	msg1->acknum = dn_htons((scp->ackxmt_oth & 0x0FFF) | 0x8000);	msg1->segnum = dn_htons(cb->segnum = (scp->numoth++ & 0x0FFF));        msg1->lsflgs = flgs;	dn_nsp_queue_xmit(sk, skb, 1);	scp->persist = dn_nsp_persist(sk);	scp->persist_fxn = dn_nsp_xmit_timeout;}static int dn_nsp_retrans_conninit(struct sock *sk){	struct dn_scp *scp = &sk->protinfo.dn;	if (scp->state == DN_CI)		dn_nsp_send_conninit(sk, NSP_RCI);	return 0;}void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg){	struct dn_scp *scp = &sk->protinfo.dn;	struct sk_buff *skb = NULL;	struct nsp_conn_init_msg *msg;	unsigned char aux;	unsigned char menuver;	struct dn_skb_cb *cb;	unsigned char type = 1;	if ((skb = dn_alloc_skb(sk, 200, (msgflg == NSP_CI) ? sk->allocation : GFP_ATOMIC)) == NULL)		return;	cb  = (struct dn_skb_cb *)skb->cb;	msg = (struct nsp_conn_init_msg *)skb_put(skb,sizeof(*msg));	msg->msgflg	= msgflg;	msg->dstaddr	= 0x0000;		/* Remote Node will assign it*/	msg->srcaddr	= sk->protinfo.dn.addrloc;	msg->services	= 1 | NSP_FC_NONE;	/* Requested flow control    */	msg->info	= 0x03;			/* Version Number            */		msg->segsize	= dn_htons(1459);	/* Max segment size	     */		if (scp->peer.sdn_objnum)		type = 0;	skb_put(skb, dn_sockaddr2username(&scp->peer, skb->tail, type));	skb_put(skb, dn_sockaddr2username(&scp->addr, skb->tail, 2));	menuver = DN_MENUVER_ACC | DN_MENUVER_USR;	if (scp->peer.sdn_flags & SDF_PROXY)		menuver |= DN_MENUVER_PRX;	if (scp->peer.sdn_flags & SDF_UICPROXY)		menuver |= DN_MENUVER_UIC;	*skb_put(skb, 1) = menuver;	/* Menu Version		*/		aux = scp->accessdata.acc_userl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux);	aux = scp->accessdata.acc_passl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux);	aux = scp->accessdata.acc_accl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux);	aux = scp->conndata_out.opt_optl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux);	sk->protinfo.dn.persist = dn_nsp_persist(sk);	sk->protinfo.dn.persist_fxn = dn_nsp_retrans_conninit;	cb->rt_flags = DN_RT_F_RQR;	dn_nsp_send(skb);	}

⌨️ 快捷键说明

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