udp.c
来自「mcf5307实验源代码」· C语言 代码 · 共 467 行 · 第 1/2 页
C
467 行
/* */
/* Get the data from the UDP buffer and transfer it into your buffer. */
/* Returns the number of bytes transferred or -1 of none available. */
/* */
/* CALLED BY */
/* bootp */
/* NU_Recv_From */
/* */
/* CALLS */
/* */
/* */
/*************************************************************************/
int16 neturead (struct uport *uptr, char *buffer, struct addr_struct *from,
struct sock_struct *sockptr)
{
UDPKT *pkt_ptr;
int16 datalen;
/* Check to see if there are any packets waiting. */
if (uptr->dgram_list.head == NU_NULL)
return (NU_NO_DATA_TRANSFER);
#ifndef POINT_TO_POINT
/* Set up a pointer to the packet stored in first buffer in the list */
pkt_ptr = (UDPKT *)uptr->dgram_list.head->packet;
#else
#ifdef NU_PPP
/* Set up a pointer to the packet stored in first buffer in the list */
pkt_ptr = (UDPKT *)(uptr->dgram_list.head->data_ptr - sizeof(UDPLAYER) - sizeof(DLAYER) - sizeof(IPLAYER));
#else
/* Set up a pointer to the packet stored in first buffer in the list */
pkt_ptr = (UDPKT *)(uptr->dgram_list.head->packet - sizeof (DLAYER));
#endif
#endif
/* Move the data into the caller's buffer. */
memcpy ((void *)buffer, (const void *)pkt_ptr->data,
uptr->dgram_list.head->data_len);
/* Get his IP number. */
memcpy (&(from->id), pkt_ptr->i.ipsource, 4);
/* Get his port number. */
from->port = (int16)intswap(pkt_ptr->u.source);
/* Update the socket descriptor with foreign address
information. */
memcpy (&(sockptr->foreign_addr.ip_num), pkt_ptr->i.ipsource, 4);
sockptr->foreign_addr.port_num = (int16)intswap(pkt_ptr->u.source);
/* Preserve the amount of data that was copied so that it can be returned
below. */
datalen = uptr->dgram_list.head->data_len;
/* Place this buffer back onto the free list. */
dll_update_lists(&uptr->dgram_list, &buffer_freelist);
/* Update the number of buffered datagrams. */
uptr->in_dgrams--;
return (datalen);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netulisten (int16) */
/* */
/* DESCRIPTION */
/* */
/* Specify which UDP port number to listen to -- can only listen to */
/* one port at a time. */
/* */
/* CALLED BY */
/* bootp */
/* */
/* CALLS */
/* */
/* */
/*************************************************************************/
void netulisten(int16 port)
{
ulist.listen = (uint16)port;
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netusend (struct uport *, uint8 *, int16) */
/* */
/* DESCRIPTION */
/* */
/* Send some data out in a udp packet ( uses the preinitialized data */
/* in the port packet *ulist.udpout* ) */
/* */
/* Returns 0 on ok send, non-zero for an error */
/* */
/* CALLED BY */
/* sendbootp */
/* senddom */
/* NU_Send_To */
/* */
/* CALLS */
/* */
/* intswap */
/* NET_Send */
/* netdlayer */
/* tcpcheck */
/* ipcheck */
/* */
/*************************************************************************/
int16 netusend (struct uport *uptr, uint8 *buffer, uint16 nbytes,
uint16 sock_options)
{
struct acache *pc;
UDPKT *udp_pkt;
struct pqueue HUGE *buf_ptr;
/* Don't send more than we have concluded is our maximum. */
if (nbytes > UMAXLEN)
nbytes = UMAXLEN;
/* Allocate a buffer to place the packet in. */
buf_ptr = (struct pqueue HUGE *)dll_dequeue((tqe_t *)&buffer_freelist);
if(buf_ptr == NU_NULL)
{
return (NU_NO_BUFFERS);
}
udp_pkt = (UDPKT *)buf_ptr->packet;
memcpy ((void *)udp_pkt, (const void *)&uptr->out,
sizeof(DLAYER) + sizeof(IPLAYER) + sizeof(UDPLAYER));
/* Make sure that we have the right dlayer address. */
/* If we wish to broadcast then simply copy the dlayer broadcast
* address to the destination. Else we need to look up the
* dlayer address.
*/
if (memcmp(uptr->out.i.ipdest, (void *)broadip, 4) == 0)
{
if ((sock_options & SO_BROADCAST) == 0)
{
dll_enqueue((tqe_t *)&buffer_freelist, (tqe_t *)buf_ptr);
return (NU_ACCES);
}
/* Copy the dlayer broadcast address */
memcpy ((void *)udp_pkt->d.dest, (const void *)broadaddr,
DADDLEN);
}
else
{
#ifndef POINT_TO_POINT
pc = (struct acache *)netdlayer (uptr->out.i.ipdest);
if (pc == NU_NULL)
{
/* Increment the number of packets that could not be delivered. */
SNMP_ipOutNoRoutes_Inc;
dll_enqueue((tqe_t *)&buffer_freelist, (tqe_t *)buf_ptr);
return (-2);
}
/* Pick up his physical address */
memcpy ((void *)udp_pkt->d.dest, (const void *)pc->hrd,
DADDLEN);
#endif
}
/* Set up the checksum header. */
memcpy ((void *)uptr->tcps.source, (const void *)nnipnum, 4);
memcpy ((void *)uptr->tcps.dest, (const void *)uptr->out.i.ipdest,
4);
uptr->tcps.tcplen = intswap ((uint16)(nbytes + sizeof (UDPLAYER)));
/* Set up the UDP header. */
/* Get the length of the buffer. */
udp_pkt->u.length = intswap ((uint16)(nbytes + sizeof (UDPLAYER)));
/* Move the data into the output buffer. */
memcpy ((void *)udp_pkt->data, (const void *)buffer, nbytes);
/* Calculate the checksum. */
udp_pkt->u.check = tcpcheck ((uint16 *) &uptr->tcps,
(uint16 *) &uptr->out.u,
(uint16)(nbytes + sizeof(UDPLAYER)));
/********************* DANGER DANGER **********************/
/* */
/* THIS NEXT STATEMENT IS BECAUSE THE CHECKSUM IS NOT */
/* WORKING. */
/* */
/********************* DANGER DANGER **********************/
udp_pkt->u.check = 0;
/* Set up the IP header information. */
/* Set up the protocol type. */
udp_pkt->i.protocol = PROTUDP;
/* Get IP header length. */
udp_pkt->i.tlen = intswap ((uint16)(nbytes + sizeof (IPLAYER) +
sizeof (UDPLAYER)));
/* Get the IP identifier. */
udp_pkt->i.ident = intswap ((uint16)nnipident++);
/* Calculate the checksum for the IP header. */
udp_pkt->i.check = 0;
udp_pkt->i.check = ipcheck ((uint16 *) &udp_pkt->i, 10);
/* Increment the number of IP packets transmitted. */
SNMP_ipOutRequests_Inc;
/* Increment the number of UDP datagrams transmitted. */
SNMP_udpoutDatagrams_Inc;
/* Send the packet. */
NET_Send(buf_ptr, (uint16)(nbytes + sizeof(DLAYER) + sizeof(IPLAYER) +
sizeof(UDPLAYER)), OTHER_PKT);
/* If the send went ok, then return the number of bytes sent. */
return((int16)nbytes);
} /* end netusend */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?