📄 tcputil.c
字号:
/* see if it's an exact match */
if((so->fhost == pip->ip_src) &&
(so->lhost == pip->ip_dest) &&
(so->fport == ptcp->th_sport))
{
return so; /* got exact match */
}
/* see if this one is a wildcard match */
if(((so->fhost == 0) || (so->fhost == pip->ip_src)) &&
((so->lhost == 0) || (so->lhost == pip->ip_dest)) &&
((so->fport == 0) || (so->fport == ptcp->th_sport)))
{
wild = so; /* remember wildcard match, but keep looking */
}
}
#ifdef NPDEBUG
if(wild && (wild->tp->t_state != TCPS_LISTEN))
{
dtrap("tcputil 4\n");
}
#endif /* NPDEBUG */
return wild; /* return partial match or null */
}
/* FUNCTION: m_delsocket()
*
* Delete the passed socket. Removes the structure from msoq and
* releases the memory.
*
* Attached tcpcbs (tp) are NOT freed.
*
* PARAM1: socket to delete
*
* RETURNS: nothing
*/
void
m_delsocket(M_SOCK so)
{
M_SOCK tmp; /* scratch for queue lookup; */
M_SOCK last; /* for queue deletion; */
so_flush(so); /* free any data buffers */
/* search global list for socket to dequeue */
last = NULL;
ENTER_CRIT_SECTION(&msoq);
for(tmp = (M_SOCK)msoq.q_head; tmp; tmp = tmp->next)
{
if(tmp == so) /* found socket to drop */
{
if(msoq.q_head == (qp)so) /* deleting head? */
msoq.q_head = (qp)so->next;
else /* not deleting head; just unlink */
last->next = tmp->next;
/* if deleting tail, update queue */
if(msoq.q_tail == (qp)so)
msoq.q_tail = (qp)last;
msoq.q_len--;
break;
}
last = tmp;
}
EXIT_CRIT_SECTION(&msoq);
msoq_check();
if(!tmp)
{
dtrap("tcputil 5\n"); /* socket not in list */
return;
}
so->tp = NULL; /* prevent further tp references via socket */
SOC_FREE(so);
}
/* FUNCTION: m_template()
*
* Create template to be used to send tcp packets on a connection.
* Call after host entry created, allocates an mbuf and fills
* in a skeletal tcp/ip header, minimizing the amount of work
* necessary when the connection is used.
*
*
* PARAM1: struct tcpcb * tp
*
* RETURNS:
*/
void
m_template(struct tcpcb * tp)
{
M_SOCK so;
struct tcpiphdr * n;
so = (M_SOCK)tp->t_inpcb;
#ifdef NPDEBUG
if(!so)
{
dtrap("tcputil 6\n");
}
#endif
/* set local pointer and tp back pointer to socket buffer */
n = tp->t_template = (struct tcpiphdr *)(&so->t_template[0]);
MEMSET(n, 0, 40);
/* fill in template TCP/IP header fields we know at this point */
n->ti_i.ip_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
n->ti_i.ip_src = so->lhost;
n->ti_i.ip_dest = so->fhost;
n->ti_t.th_sport = so->lport;
n->ti_t.th_dport = so->fport;
n->ti_t.th_doff = (5 << 4);
msoq_check();
return;
}
/* FUNCTION: m_connected()
*
* Called to handle state change when a socket connects.
*
* PARAM1: socket that connected
*
* RETURNS: nothing
*/
void
m_connected(M_SOCK so)
{
so->state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING);
so->state |= SS_ISCONNECTED;
so->error = 0;
/* set flag to do callback to indicate socket connected. We defer the
* call back until after the packet which created the connected state is
* fully processed so that that callback routine can safly send a data
* packet (or even start a shutdown).
*/
so->tp->t_flags |= TF_OPENUP;
}
/* FUNCTION: m_disconnecting()
*
* Called by the tcp layer when a socket is disconnecting. Sets
* the required flags and does the wakeup() calls.
*
* PARAM1: M_SOCK so
*
* RETURNS:
*/
void
m_disconnecting(M_SOCK so)
{
so->state &= ~SS_ISCONNECTING;
so->state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
tcp_wakeup(&so->sendq);
tcp_wakeup(&so->rcvdq);
}
void
m_disconnected(M_SOCK so)
{
so->state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
so->state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
tcp_wakeup (&so->sendq);
tcp_wakeup (&so->rcvdq);
}
/* FUNCTION: m_sbdrop()
*
* Drop packets from the head of an msock data queue. This is called when
* an ack is received for buffered send data.
*
* PARAM1: queue * que - que to drop from
* PARAM2: unsigned todrop - number of bytes to drop
*
* RETURNS: 0 if OK or BSD error.
*/
int
m_sbdrop(struct m_sockbuf * que, unsigned todrop)
{
PACKET pkt;
while(todrop)
{
pkt = (PACKET)(que->p_head); /* head packet in queue */
if(!pkt)
{
dtrap("tcputil 7\n"); /* tried to drop more than we had? */
return EINVAL;
}
/* see if we can drop the whole packet */
if(todrop >= pkt->m_len)
{
todrop -= pkt->m_len;
tcp_pktfree(get_soq(que));
}
else if(todrop > 0) /* other guy acked a partial packet */
{
dtrap("tcputil 8\n"); /* watch first time -JB- */
pkt->m_len -= todrop; /* strip data from front of pkt */
pkt->m_data += todrop;
return 0; /* done */
}
else /* todrop was negative */
{
dtrap("tcputil 9\n"); /* programming error */
return 0;
}
}
return 0;
}
/* FUNCTION: get_soq()
*
* Unlink and return packet at head of socket data que passed
*
* PARAM1: struct m_sockbuf * que
*
* RETURNS: PACKET that was at head of queue
*/
PACKET
get_soq(struct m_sockbuf * que)
{
PACKET pkt;
if(que->p_head == NULL)
return NULL;
ENTER_CRIT_SECTION(que);
pkt = que->p_head;
que->p_head = pkt->m_next;
if(pkt == que->p_tail) /* if packet is also tail... */
que->p_tail = NULL; /* ...then que is now empty */
que->sb_cc -= pkt->m_len; /* deduct pkt data length from total */
EXIT_CRIT_SECTION(que);
return pkt;
}
/* FUNCTION: put_soq()
*
* Add a packet to the tail of socket data que.
*
* PARAM1: struct m_sockbuf * que
* PARAM2: PACKET pkt to add
*
* RETURNS: void
*/
void
put_soq(struct m_sockbuf * que, PACKET pkt)
{
ENTER_CRIT_SECTION(que);
pkt->m_next = NULL; /* no next, will be last pkt in que */
if(que->p_tail)
que->p_tail->m_next = pkt;
que->p_tail = pkt; /* make it the new tail */
if(que->p_head == NULL) /* if queue was empty... */
que->p_head = pkt; /* packet is now head & tail */
que->sb_cc += pkt->m_len; /* add pkt data length to total */
EXIT_CRIT_SECTION(que);
}
/* FUNCTION: socket_queue_name()
*
* this function checks to see if the passed in PACKET structure is
* in one of the socket queues. returns a pointer to name describing
* what queue the PACKET structure
*
*
* PARAM1: PACKET pkt
*
* RETURNS:
*/
#ifdef IN_MENUS
char *
socket_queue_name(PACKET pkt)
{
M_SOCK so;
PACKET tmp;
for(so = (M_SOCK)msoq.q_head; so; so = so->next)
{
/* check to see if the pkt is in the rcv mbuf queue */
for(tmp = so->rcvdq.p_head; tmp; tmp = tmp->m_next)
if(tmp == pkt)
return "sor";
/* check to see if the pkt is in the send mbuf queue */
for(tmp = so->sendq.p_head; tmp; tmp = tmp->m_next)
if(tmp == pkt)
return "snd";
}
/* not found in any socket queue */
return 0;
}
#endif /* IN_MENUS */
#ifndef TCPWAKE_ALREADY
/* the tcp process sleep and wakeup system.
* these are the superloop versions, for other versions you need
* to define them in you port files and set TCPWAKE_ALREADY.
*
* A true multitasking version of these is in ..\misclib\netmain.c
*/
void * last_arg; /* for debugging */
/* FUNCTION: tcp_sleep()
*
* PARAM1: void * timeout
*
* RETURNS: void
*/
void
tcp_sleep(void * timeout)
{
UNLOCK_NET_RESOURCE(NET_RESID);
tk_yield(); /* let the system run a bit... */
LOCK_NET_RESOURCE(NET_RESID);
last_arg = timeout;
}
/* FUNCTION: tcp_wakeup()
*
* PARAM1: void * wake
*
* RETURNS: void
*/
void
tcp_wakeup(void * wake)
{
last_arg = wake;
}
#endif /* TCPWAKE_ALREADY */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -