本文整理汇总了C++中pbuf_header函数的典型用法代码示例。如果您正苦于以下问题:C++ pbuf_header函数的具体用法?C++ pbuf_header怎么用?C++ pbuf_header使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了pbuf_header函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ip_reass
//.........这里部分代码省略.........
goto nullreturn;
}
}
/* Look for the datagram the fragment belongs to in the current datagram queue,
* remembering the previous in the queue for later dequeueing. */
for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) {
/* Check if the incoming fragment matches the one currently present
in the reassembly buffer. If so, we proceed with copying the
fragment into the buffer. */
if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n",
ntohs(IPH_ID(fraghdr))));
IPFRAG_STATS_INC(ip_frag.cachehit);
break;
}
ipr_prev = ipr;
}
if (ipr == NULL) {
/* Enqueue a new datagram into the datagram queue */
ipr = ip_reass_enqueue_new_datagram(fraghdr, clen);
/* Bail if unable to enqueue */
if(ipr == NULL) {
goto nullreturn;
}
} else {
if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
/* ipr->iphdr is not the header from the first fragment, but fraghdr is
* -> copy fraghdr into ipr->iphdr since we want to have the header
* of the first fragment (for ICMP time exceeded and later, for copying
* all options, if supported)*/
SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN);
}
}
/* Track the current number of pbufs current 'in-flight', in order to limit
the number of fragments that may be enqueued at any one time */
ip_reass_pbufcount += clen;
/* At this point, we have either created a new entry or pointing
* to an existing one */
/* check for 'no more fragments', and update queue entry*/
if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) {
ipr->flags |= IP_REASS_FLAG_LASTFRAG;
ipr->datagram_len = offset + len;
LWIP_DEBUGF(IP_REASS_DEBUG,
("ip_reass: last fragment seen, total len %"S16_F"\n",
ipr->datagram_len));
}
/* find the right place to insert this pbuf */
/* @todo: trim pbufs if fragments are overlapping */
if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) {
/* the totally last fragment (flag more fragments = 0) was received at least
* once AND all fragments are received */
ipr->datagram_len += IP_HLEN;
/* save the second pbuf before copying the header over the pointer */
r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf;
/* copy the original ip header back to the first pbuf */
fraghdr = (struct ip_hdr*)(ipr->p->payload);
SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
IPH_LEN_SET(fraghdr, htons(ipr->datagram_len));
IPH_OFFSET_SET(fraghdr, 0);
IPH_CHKSUM_SET(fraghdr, 0);
/* @todo: do we need to set calculate the correct checksum? */
IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
p = ipr->p;
/* chain together the pbufs contained within the reass_data list. */
while(r != NULL) {
iprh = (struct ip_reass_helper*)r->payload;
/* hide the ip header for every succeding fragment */
pbuf_header(r, -IP_HLEN);
pbuf_cat(p, r);
r = iprh->next_pbuf;
}
/* release the sources allocate for the fragment queue entry */
ip_reass_dequeue_datagram(ipr, ipr_prev);
/* and adjust the number of pbufs currently queued for reassembly. */
ip_reass_pbufcount -= pbuf_clen(p);
/* Return the pbuf chain */
return p;
}
/* the datagram is not (yet?) reassembled completely */
LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount));
return NULL;
nullreturn:
LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n"));
IPFRAG_STATS_INC(ip_frag.drop);
pbuf_free(p);
return NULL;
}
示例2: csi_eth_mac_read_frame
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *low_level_input(struct netif *netif)
{
struct pbuf *p, *q;
int32_t len;
int l = 0;
/* Obtain the size of the packet and put it into the "len"
variable. */
len = csi_eth_mac_read_frame(eth_mac_handle, Data_Buf, MAX_FRAMELEN);
if (len < 0) {
/* errors in rx buffer, reset enc28j60 */
LOGE(TAG, "err rxb, rst");
yoc_nic_reset();
return NULL;
} else if (len == 0) {
return NULL;
}
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL) {
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
/* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf. */
for (q = p; q != NULL; q = q->next) {
/* Read enough bytes to fill this pbuf in the chain. The
* available data in the pbuf is given by the q->len
* variable.
* This does not necessarily have to be a memcpy, you can also preallocate
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
* actually received size. In this case, ensure the tot_len member of the
* pbuf is the sum of the chained pbuf len members.
*/
/* read data into(q->payload, q->len); */
memcpy((u8_t *)q->payload, (u8_t *)&Data_Buf[l], q->len);
l = l + q->len;
}
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
if (((u8_t *)p->payload)[0] & 1) {
/* broadcast or multicast packet */
MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
} else {
/* unicast packet */
MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.recv);
} else {
/* drop packet(); */
/* error to allocate a pbuf chain of pbufs from the pool */
LOGE(TAG, "err alloc pbuf");
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
MIB2_STATS_NETIF_INC(netif, ifindiscards);
}
return p;
}
示例3: ip_input
void
ip_input(struct pbuf *p, struct netif *inp) {
struct ip_hdr *iphdr;
struct netif *netif;
PERF_START;
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
IP_STATS_INC(ip.recv);
/* identify the IP header */
iphdr = p->payload;
if (iphdr->v != 6) {
LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
pbuf_free(p);
IP_STATS_INC(ip.err);
IP_STATS_INC(ip.drop);
return;
}
/* is this packet for us? */
for(netif = netif_list; netif != NULL; netif = netif->next) {
#if IP_DEBUG
LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));
ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
LWIP_DEBUGF(IP_DEBUG, ("\n"));
#endif /* IP_DEBUG */
if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
break;
}
}
if (netif == NULL) {
/* packet not for us, route or discard */
#if IP_FORWARD
ip_forward(p, iphdr);
#endif
pbuf_free(p);
return;
}
pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
/* send to upper layers */
#if IP_DEBUG
/* LWIP_DEBUGF("ip_input: \n");
ip_debug_print(p);
LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/
#endif /* IP_DEBUG */
if(pbuf_header(p, -IP_HLEN)) {
LWIP_ASSERT("Can't move over header in packet", 0);
return;
}
switch (iphdr->nexthdr) {
case IP_PROTO_UDP:
udp_input(p, inp);
break;
case IP_PROTO_TCP:
tcp_input(p, inp);
break;
#if LWIP_ICMP
case IP_PROTO_ICMP:
icmp_input(p, inp);
break;
#endif /* LWIP_ICMP */
default:
#if LWIP_ICMP
/* send ICMP destination protocol unreachable */
icmp_dest_unreach(p, ICMP_DUR_PROTO);
#endif /* LWIP_ICMP */
pbuf_free(p);
LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n",
iphdr->nexthdr));
IP_STATS_INC(ip.proterr);
IP_STATS_INC(ip.drop);
}
PERF_STOP("ip_input");
}
示例4: START_TEST
END_TEST
/** Check that we handle malformed tcp headers, and discard the pbuf(s) */
START_TEST(test_tcp_malformed_header)
{
struct test_tcp_counters counters;
struct tcp_pcb* pcb;
struct pbuf* p;
char data[] = {1, 2, 3, 4};
ip_addr_t remote_ip, local_ip, netmask;
u16_t data_len, chksum;
u16_t remote_port = 0x100, local_port = 0x101;
struct netif netif;
struct test_tcp_txcounters txcounters;
struct tcp_hdr *hdr;
LWIP_UNUSED_ARG(_i);
/* initialize local vars */
memset(&netif, 0, sizeof(netif));
IP_ADDR4(&local_ip, 192, 168, 1, 1);
IP_ADDR4(&remote_ip, 192, 168, 1, 2);
IP_ADDR4(&netmask, 255, 255, 255, 0);
test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
data_len = sizeof(data);
/* initialize counter struct */
memset(&counters, 0, sizeof(counters));
counters.expected_data_len = data_len;
counters.expected_data = data;
/* create and initialize the pcb */
pcb = test_tcp_new_counters_pcb(&counters);
EXPECT_RET(pcb != NULL);
tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
/* create a segment */
p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
hdr = (struct tcp_hdr *)p->payload;
TCPH_HDRLEN_FLAGS_SET(hdr, 15, 0x3d1);
hdr->chksum = 0;
chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
&remote_ip, &local_ip);
hdr->chksum = chksum;
pbuf_header(p, sizeof(struct ip_hdr));
EXPECT(p != NULL);
EXPECT(p->next == NULL);
if (p != NULL) {
/* pass the segment to tcp_input */
test_tcp_input(p, &netif);
/* check if counters are as expected */
EXPECT(counters.close_calls == 0);
EXPECT(counters.recv_calls == 0);
EXPECT(counters.recved_bytes == 0);
EXPECT(counters.err_calls == 0);
}
/* make sure the pcb is freed */
EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
tcp_abort(pcb);
EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
}
示例5: udp_input
/**
* Process an incoming UDP datagram.
*
* Given an incoming UDP datagram (as a chain of pbufs) this function
* finds a corresponding UDP PCB and hands over the pbuf to the pcbs
* recv function. If no pcb is found or the datagram is incorrect, the
* pbuf is freed.
*
* @param p pbuf to be demultiplexed to a UDP PCB.
* @param inp network interface on which the datagram was received.
*
*/
void
udp_input(struct pbuf *p, struct netif *inp)
{
struct udp_hdr *udphdr;
struct udp_pcb *pcb, *prev;
struct udp_pcb *uncon_pcb;
struct ip_hdr *iphdr;
u16_t src, dest;
u8_t local_match;
u8_t broadcast;
PERF_START;
UDP_STATS_INC(udp.recv);
iphdr = (struct ip_hdr *)p->payload;
/* Check minimum length (IP header + UDP header)
* and move payload pointer to UDP header */
if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) {
/* drop short packets */
LWIP_DEBUGF(UDP_DEBUG,
("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
UDP_STATS_INC(udp.lenerr);
UDP_STATS_INC(udp.drop);
snmp_inc_udpinerrors();
pbuf_free(p);
goto end;
}
udphdr = (struct udp_hdr *)p->payload;
/* is broadcast packet ? */
broadcast = ip_addr_isbroadcast(¤t_iphdr_dest, inp);
LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
/* convert src and dest ports to host byte order */
src = ntohs(udphdr->src);
dest = ntohs(udphdr->dest);
udp_debug_print(udphdr);
/* print the UDP source and destination */
LWIP_DEBUGF(UDP_DEBUG,
("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- "
"(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
ip4_addr1_16(&iphdr->dest), ip4_addr2_16(&iphdr->dest),
ip4_addr3_16(&iphdr->dest), ip4_addr4_16(&iphdr->dest), ntohs(udphdr->dest),
ip4_addr1_16(&iphdr->src), ip4_addr2_16(&iphdr->src),
ip4_addr3_16(&iphdr->src), ip4_addr4_16(&iphdr->src), ntohs(udphdr->src)));
#if LWIP_DHCP
pcb = NULL;
/* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by
the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */
if (dest == DHCP_CLIENT_PORT) {
/* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */
if (src == DHCP_SERVER_PORT) {
if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) {
/* accept the packe if
(- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY!
- inp->dhcp->pcb->remote == ANY or iphdr->src */
if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) ||
ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), ¤t_iphdr_src))) {
pcb = inp->dhcp->pcb;
}
}
}
} else
#endif /* LWIP_DHCP */
{
prev = NULL;
local_match = 0;
uncon_pcb = NULL;
/* Iterate through the UDP pcb list for a matching pcb.
* 'Perfect match' pcbs (connected to the remote port & ip address) are
* preferred. If no perfect match is found, the first unconnected pcb that
* matches the local port and ip address gets the datagram. */
for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
local_match = 0;
/* print the PCB local and remote address */
LWIP_DEBUGF(UDP_DEBUG,
("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- "
"(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip),
ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), pcb->local_port,
ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
//.........这里部分代码省略.........
示例6: netfront_get_responses
/*
* Reads RX responses for a single packet
*/
static int netfront_get_responses(struct netfront_dev *dev,
RING_IDX rp)
{
struct netif_rx_response *rsp = &(dev->rsp);
int32_t realsize = rsp->status;
int16_t size = rsp->status;
uint16_t id = rsp->id;
uint16_t flags = rsp->flags;
RING_IDX cons = rp;
uint16_t slots = 1;
int drop = 0;
#ifdef HAVE_LWIP
struct pbuf *p;
struct pbuf *first_p;
#endif
dprintk("rx: ring: len %d %s\n", size,
(flags & NETRXF_more_data ? "(more true) ": ""));
BUG_ON(id >= NET_RX_RING_SIZE);
if (flags & NETRXF_extra_info) {
memset(dev->extras, 0, sizeof(dev->extras));
netfront_get_extras(dev, dev->extras, cons);
cons = dev->rx.rsp_cons;
}
if (flags & NETRXF_more_data) {
dprintk("rx: scan: slot 0 len %d %s\n",
size, (flags & NETRXF_more_data ? "(more true)": ""));
realsize = size + netfront_get_size(dev, cons);
}
dprintk("rx: %c%c- %"PRIi32" bytes\n",
flags & NETRXF_extra_info ? 'S' : '-',
flags & ((NETRXF_csum_blank) | (NETRXF_data_validated)) ? 'C' : '-',
realsize);
#ifdef HAVE_LWIP
if (likely(dev->netif_rx_pbuf)) {
#ifdef CONFIG_NETFRONT_PERSISTENT_GRANTS
first_p = p = netfront_alloc_pbuf(dev, realsize);
drop = (p == NULL);
#else
first_p = p = &dev->rx_buffers[id]->cpbuf.pbuf;
drop = 0;
dev->pbuf_cur = p;
#endif /* CONFIG_NETFRONT_PERSISTENT_GRANTS */
#if ETH_PAD_SIZE
if (likely(!drop))
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif /* ETH_PAD_SIZE */
}
#endif /* HAVE_LWIP */
for (;;) {
if (unlikely(rsp->status < 0 ||
(rsp->offset + rsp->status > PAGE_SIZE))) {
printk("rx: ring<%u>: status %d, flags %04x, offset %d\n",
cons + slots, size, flags, rsp->offset);
} else if (likely(!drop)) {
#ifdef CONFIG_NETFRONT_PERSISTENT_GRANTS
handle_buffer(dev, rsp, &dev->rx_buffers[id], realsize);
#else
handle_buffer(dev, rsp, dev->rx_buffers[id], realsize);
#endif
}
#ifndef CONFIG_NETFRONT_PERSISTENT_GRANTS
BUG_ON(dev->rx_buffers[id]->gref == GRANT_INVALID_REF);
gnttab_end_access(dev->rx_buffers[id]->gref);
dev->rx_buffers[id]->gref = GRANT_INVALID_REF;
dev->rx_buffers[id] = NULL;
#endif
if (!(flags & NETRXF_more_data))
break;
if (dev->rx.sring->rsp_prod <= cons + slots)
break;
rsp = RING_GET_RESPONSE(&dev->rx, cons + slots);
id = rsp->id;
BUG_ON(id >= NET_RX_RING_SIZE);
size = rsp->status;
flags = rsp->flags;
slots++;
#ifndef CONFIG_NETFRONT_PERSISTENT_GRANTS
if (likely(dev->netif_rx_pbuf && (!drop))) {
/* set tot_len */
p->tot_len = realsize;
realsize -= p->len;
/* ..and link it to next pbuf */
p->next = &dev->rx_buffers[id]->cpbuf.pbuf;
dev->pbuf_cur = p = p->next;
} else {
//.........这里部分代码省略.........
示例7: igmp_input
/**
* Called from ip_input() if a new IGMP packet is received.
*
* @param p received igmp packet, p->payload pointing to the ip header
* @param inp network interface on which the packet was received
* @param dest destination ip address of the igmp packet
*/
void
igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest)
{
struct ip_hdr * iphdr;
struct igmp_msg* igmp;
struct igmp_group* group;
struct igmp_group* groupref;
/* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */
iphdr = p->payload;
if (pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4)) || (p->len < IGMP_MINLEN)) {
pbuf_free(p);
IGMP_STATS_INC(igmp.lenerr);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n"));
return;
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from "));
ip_addr_debug_print(IGMP_DEBUG, &(iphdr->src));
LWIP_DEBUGF(IGMP_DEBUG, (" to address "));
ip_addr_debug_print(IGMP_DEBUG, &(iphdr->dest));
LWIP_DEBUGF(IGMP_DEBUG, (" on if %x\n", (int) inp));
/* Now calculate and check the checksum */
igmp = (struct igmp_msg *)p->payload;
if (inet_chksum(igmp, p->len)) {
pbuf_free(p);
IGMP_STATS_INC(igmp.chkerr);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n"));
return;
}
/* Packet is ok so find an existing group */
group = igmp_lookfor_group(inp, dest); /* use the incoming IP address! */
/* If group can be found or create... */
if (!group) {
pbuf_free(p);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
return;
}
/* NOW ACT ON THE INCOMING MESSAGE TYPE... */
switch (igmp->igmp_msgtype) {
case IGMP_MEMB_QUERY: {
/* IGMP_MEMB_QUERY to the "all systems" address ? */
if ((ip_addr_cmp(dest, &allsystems)) && (igmp->igmp_group_address.addr == 0)) {
/* THIS IS THE GENERAL QUERY */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
if (igmp->igmp_maxresp == 0) {
IGMP_STATS_INC(igmp.v1_rxed);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
}
IGMP_STATS_INC(igmp.group_query_rxed);
groupref = igmp_group_list;
while (groupref) {
/* Do not send messages on the all systems group address! */
if ((groupref->interface == inp) && (!(ip_addr_cmp(&(groupref->group_address), &allsystems)))) {
igmp_delaying_member( groupref, igmp->igmp_maxresp);
}
groupref = groupref->next;
}
} else {
/* IGMP_MEMB_QUERY to a specific group ? */
if (group->group_address.addr != 0) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group "));
ip_addr_debug_print(IGMP_DEBUG, &group->group_address);
if (ip_addr_cmp (dest, &allsystems)) {
LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
/* we first need to re-lookfor the group since we used dest last time */
group = igmp_lookfor_group(inp, &igmp->igmp_group_address);
} else {
LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
}
if (group != NULL) {
IGMP_STATS_INC(igmp.unicast_query);
igmp_delaying_member( group, igmp->igmp_maxresp);
}
}
}
break;
}
case IGMP_V2_MEMB_REPORT: {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
IGMP_STATS_INC(igmp.report_rxed);
if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
/* This is on a specific group we have already looked up */
group->timer = 0; /* stopped */
//.........这里部分代码省略.........
示例8: ip6_reass
//.........这里部分代码省略.........
ipr->identification = frag_hdr->_identification;
/* copy the nexth field */
ipr->nexth = frag_hdr->_nexth;
}
/* Check if we are allowed to enqueue more datagrams. */
if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
#if IP_REASS_FREE_OLDEST
ip6_reass_remove_oldest_datagram(ipr, clen);
if ((ip6_reass_pbufcount + clen) <= IP_REASS_MAX_PBUFS) {
/* re-search ipr_prev since it might have been removed */
for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
if (ipr_prev->next == ipr) {
break;
}
}
} else
#endif /* IP_REASS_FREE_OLDEST */
{
/* @todo: send ICMPv6 time exceeded here? */
/* drop this pbuf */
IP6_FRAG_STATS_INC(ip6_frag.memerr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
}
}
/* Overwrite Fragment Header with our own helper struct. */
#if IPV6_FRAG_COPYHEADER
if (IPV6_FRAG_REQROOM > 0) {
/* Make room for struct ip6_reass_helper (only required if sizeof(void*) > 4).
This cannot fail since we already checked when receiving this fragment. */
err_t hdrerr = pbuf_header_force(p, IPV6_FRAG_REQROOM);
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == ERR_OK);
}
#else /* IPV6_FRAG_COPYHEADER */
LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
#endif /* IPV6_FRAG_COPYHEADER */
iprh = (struct ip6_reass_helper *)p->payload;
iprh->next_pbuf = NULL;
iprh->start = (offset & IP6_FRAG_OFFSET_MASK);
iprh->end = (offset & IP6_FRAG_OFFSET_MASK) + len;
/* find the right place to insert this pbuf */
/* Iterate through until we either get to the end of the list (append),
* or we find on with a larger offset (insert). */
for (q = ipr->p; q != NULL;) {
iprh_tmp = (struct ip6_reass_helper*)q->payload;
if (iprh->start < iprh_tmp->start) {
#if IP_REASS_CHECK_OVERLAP
if (iprh->end > iprh_tmp->start) {
/* fragment overlaps with following, throw away */
IP6_FRAG_STATS_INC(ip6_frag.proterr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
}
if (iprh_prev != NULL) {
if (iprh->start < iprh_prev->end) {
/* fragment overlaps with previous, throw away */
IP6_FRAG_STATS_INC(ip6_frag.proterr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
}
}
示例9: raw_sendto
/**
* Send the raw IP packet to the given address. Note that actually you cannot
* modify the IP headers (this is inconsistent with the receive callback where
* you actually get the IP headers), you can only specify the IP payload here.
* It requires some more changes in lwIP. (there will be a raw_send() function
* then.)
*
* @param pcb the raw pcb which to send
* @param p the IP payload to send
* @param ipaddr the destination address of the IP packet
*
*/
err_t raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) {
err_t err;
struct netif *netif;
ip_addr_t *src_ip;
struct pbuf *q; /* q will be sent down the stack */
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
/* not enough space to add an IP header to first pbuf in given p chain? */
if (pbuf_header(p, IP_HLEN)) {
/* allocate header in new pbuf */
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("raw_sendto: could not allocate header\n"));
return ERR_MEM;
}
if (p->tot_len != 0) {
/* chain header q in front of given pbuf p */
pbuf_chain(q, p);
}
/* { first pbuf q points to header pbuf } */
LWIP_DEBUGF(RAW_DEBUG,
("raw_sendto: added header pbuf %p before given pbuf %p\n",
(void *) q, (void *) p));
} else {
/* first pbuf q equals given pbuf */
q = p;
if (pbuf_header(q, -IP_HLEN)) {
LWIP_ASSERT("Can't restore header we just removed!", 0);
return ERR_MEM;
}
}
if ((netif = ip_route(ipaddr)) == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING,
("raw_sendto: No route to %" U16_F ".%" U16_F ".%" U16_F
".%" U16_F "\n",
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
#if IP_SOF_BROADCAST
/* broadcast filter? */
if (!ip_get_option(pcb, SOF_BROADCAST) &&
ip_addr_isbroadcast(ipaddr, netif)) {
LWIP_DEBUGF(
RAW_DEBUG | LWIP_DBG_LEVEL_WARNING,
("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *) pcb));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_VAL;
}
#endif /* IP_SOF_BROADCAST */
if (ip_addr_isany(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = &(netif->ip_addr);
} else {
/* use RAW PCB local IP address as source address */
src_ip = &(pcb->local_ip);
}
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
err =
ip_output_if(q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
NETIF_SET_HWADDRHINT(netif, NULL);
/* did we chain a header earlier? */
if (q != p) {
/* free the header */
pbuf_free(q);
}
return err;
}
示例10: udp_input
/*-----------------------------------------------------------------------------------*/
void
udp_input(struct pbuf *p, struct netif *inp)
{
struct udp_hdr *udphdr;
struct udp_pcb *pcb;
struct ip_hdr *iphdr;
uint16_t src, dest;
#ifdef UDP_STATS
++stats.udp.recv;
#endif /* UDP_STATS */
iphdr = p->payload;
pbuf_header(p, -(UDP_HLEN + IPH_HL(iphdr) * 4));
udphdr = (struct udp_hdr *)((uint8_t *)p->payload - UDP_HLEN);
DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %d\n", p->tot_len));
src = NTOHS(udphdr->src);
dest = NTOHS(udphdr->dest);
#if UDP_DEBUG
udp_debug_print(udphdr);
#endif /* UDP_DEBUG */
/* Demultiplex packet. First, go for a perfect match. */
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(UDP_DEBUG, ("udp_input: pcb local port %d (dgram %d)\n",
pcb->local_port, ntohs(udphdr->dest)));
if(pcb->remote_port == src &&
pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
break;
}
}
if(pcb == NULL) {
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(UDP_DEBUG, ("udp_input: pcb local port %d (dgram %d)\n",
pcb->local_port, dest));
if(pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
break;
}
}
}
/* Check checksum if this is a match or if it was directed at us. */
/* if(pcb != NULL ||
ip_addr_cmp(&inp->ip_addr, &iphdr->dest)) {*/
if(pcb != NULL) {
DEBUGF(UDP_DEBUG, ("udp_input: calculating checksum\n"));
pbuf_header(p, UDP_HLEN);
#ifdef IPv6
if(iphdr->nexthdr == IP_PROTO_UDPLITE) {
#else
if(IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
#endif /* IPv4 */
/* Do the UDP Lite checksum */
if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
(struct ip_addr *)&(iphdr->dest),
IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
DEBUGF(UDP_DEBUG, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
#ifdef UDP_STATS
++stats.udp.chkerr;
++stats.udp.drop;
#endif /* UDP_STATS */
pbuf_free(p);
goto end;
}
} else {
if(udphdr->chksum != 0) {
if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
(struct ip_addr *)&(iphdr->dest),
IP_PROTO_UDP, p->tot_len) != 0) {
DEBUGF(UDP_DEBUG, ("udp_input: UDP datagram discarded due to failing checksum\n"));
#ifdef UDP_STATS
++stats.udp.chkerr;
++stats.udp.drop;
#endif /* UDP_STATS */
pbuf_free(p);
goto end;
}
}
}
pbuf_header(p, -UDP_HLEN);
if(pcb != NULL) {
pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
//.........这里部分代码省略.........
示例11: tcpdump
/*-----------------------------------------------------------------------------------*/
void
tcpdump(struct pbuf *p)
{
struct ip_hdr *iphdr;
struct tcp_hdr *tcphdr;
#if LWIP_UDP
struct udp_hdr *udphdr;
#endif
char flags[5];
int i;
int len;
int offset;
if (file == NULL) {
return;
}
#ifdef IPv4
iphdr = (struct ip_hdr *)p->payload;
switch (IPH_PROTO(iphdr)) {
#if LWIP_TCP
case IP_PROTO_TCP:
tcphdr = (struct tcp_hdr *)((char *)iphdr + IP_HLEN);
pbuf_header(p, -IP_HLEN);
if (inet_chksum_pseudo(p, (ip_addr_t *)&(iphdr->src),
(ip_addr_t *)&(iphdr->dest),
IP_PROTO_TCP, p->tot_len) != 0) {
LWIP_DEBUGF(TCPDUMP_DEBUG, ("tcpdump: IP checksum failed!\n"));
/* fprintf(file, "chksum 0x%lx ", tcphdr->chksum);
tcphdr->chksum = 0;
fprintf(file, "should be 0x%lx ", inet_chksum_pseudo(p, (ip_addr_t *)&(iphdr->src),
(ip_addr_t *)&(iphdr->dest),
IP_PROTO_TCP, p->tot_len));*/
fprintf(file, "!chksum ");
}
i = 0;
if (TCPH_FLAGS(tcphdr) & TCP_SYN) {
flags[i++] = 'S';
}
if (TCPH_FLAGS(tcphdr) & TCP_PSH) {
flags[i++] = 'P';
}
if (TCPH_FLAGS(tcphdr) & TCP_FIN) {
flags[i++] = 'F';
}
if (TCPH_FLAGS(tcphdr) & TCP_RST) {
flags[i++] = 'R';
}
if (i == 0) {
flags[i++] = '.';
}
flags[i++] = 0;
fprintf(file, "%d.%d.%d.%d.%u > %d.%d.%d.%d.%u: ",
(int)(ntohl(iphdr->src.addr) >> 24) & 0xff,
(int)(ntohl(iphdr->src.addr) >> 16) & 0xff,
(int)(ntohl(iphdr->src.addr) >> 8) & 0xff,
(int)(ntohl(iphdr->src.addr) >> 0) & 0xff,
ntohs(tcphdr->src),
(int)(ntohl(iphdr->dest.addr) >> 24) & 0xff,
(int)(ntohl(iphdr->dest.addr) >> 16) & 0xff,
(int)(ntohl(iphdr->dest.addr) >> 8) & 0xff,
(int)(ntohl(iphdr->dest.addr) >> 0) & 0xff,
ntohs(tcphdr->dest));
offset = TCPH_HDRLEN(tcphdr);
len = ntohs(IPH_LEN(iphdr)) - offset * 4 - IP_HLEN;
if (len != 0 || flags[0] != '.') {
fprintf(file, "%s %u:%u(%u) ",
flags,
ntohl(tcphdr->seqno),
ntohl(tcphdr->seqno) + len,
len);
}
if (TCPH_FLAGS(tcphdr) & TCP_ACK) {
fprintf(file, "ack %u ",
ntohl(tcphdr->ackno));
}
fprintf(file, "wnd %u\n",
ntohs(tcphdr->wnd));
fflush(file);
pbuf_header(p, IP_HLEN);
break;
#endif /* LWIP_TCP */
#if LWIP_UDP
case IP_PROTO_UDP:
udphdr = (struct udp_hdr *)((char *)iphdr + IP_HLEN);
pbuf_header(p, -IP_HLEN);
if (inet_chksum_pseudo(p, (ip_addr_t *)&(iphdr->src),
(ip_addr_t *)&(iphdr->dest),
IP_PROTO_UDP, p->tot_len) != 0) {
LWIP_DEBUGF(TCPDUMP_DEBUG, ("tcpdump: IP checksum failed!\n"));
//.........这里部分代码省略.........
示例12: ip_input
//.........这里部分代码省略.........
* If the destination IP address is IP_HDRINCL, p is assumed to already
* include an IP header and p->payload points to it instead of the data.
*
* @param p the packet to send (p->payload points to the data, e.g. next
protocol header; if dest == IP_HDRINCL, p already includes an IP
header and p->payload points to that IP header)
* @param src the source IP address to send from (if src == IP_ADDR_ANY, the
* IP address of the netif used to send is used as source address)
* @param dest the destination IP address to send the packet to
* @param ttl the TTL value to be set in the IP header
* @param tos the TOS value to be set in the IP header
* @param proto the PROTOCOL to be set in the IP header
* @param netif the netif on which to send this packet
* @return ERR_OK if the packet was sent OK
* ERR_BUF if p doesn't have enough space for IP/LINK headers
* returns errors returned by netif->output
*
* @note ip_id: RFC791 "some host may be able to simply use
* unique identifiers independent of destination"
*/
err_t
ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl, u8_t tos,
u8_t proto, struct netif *netif)
{
struct ip_hdr *iphdr;
static u16_t ip_id = 0;
snmp_inc_ipoutrequests();
/* Should the IP header be generated or is it already included in p? */
if (dest != IP_HDRINCL) {
/* generate IP header */
if (pbuf_header(p, IP_HLEN)) {
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
IP_STATS_INC(ip.err);
snmp_inc_ipoutdiscards();
return ERR_BUF;
}
iphdr = p->payload;
LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
(p->len >= sizeof(struct ip_hdr)));
IPH_TTL_SET(iphdr, ttl);
IPH_PROTO_SET(iphdr, proto);
ip_addr_set(&(iphdr->dest), dest);
IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);
IPH_LEN_SET(iphdr, htons(p->tot_len));
IPH_OFFSET_SET(iphdr, 0);
IPH_ID_SET(iphdr, htons(ip_id));
++ip_id;
if (ip_addr_isany(src)) {
ip_addr_set(&(iphdr->src), &(netif->ip_addr));
} else {
ip_addr_set(&(iphdr->src), src);
}
IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
#endif
示例13: icmp_input
/* 调用途径:ethernetif_input() -> ethernet_input() -> ip_input() -> icmp_input()*/
void
icmp_input(struct pbuf *p, struct netif *inp)
{
u8_t type;
#ifdef LWIP_DEBUG
u8_t code;
#endif /* LWIP_DEBUG */
struct icmp_echo_hdr *iecho;
struct ip_hdr *iphdr;
/* IP 地址 */
struct ip_addr tmpaddr;
s16_t hlen;
ICMP_STATS_INC(icmp.recv);
snmp_inc_icmpinmsgs();
/* 指向IP首部 */
iphdr = p->payload;
/* 获得IP报头长度 */
hlen = IPH_HL(iphdr) * 4;
/* pbuf的payload向后移动到IP载荷,即ICMP报头处
* 如果IP的载荷小于4字节,则跳到lenerr处,释放pbuf
*/
if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
goto lenerr;
}
/* 获取ICMP报头中的类型 */
type = *((u8_t *)p->payload);
#ifdef LWIP_DEBUG
code = *(((u8_t *)p->payload)+1);
#endif /* LWIP_DEBUG */
switch (type) {
/* 如果ICMP类型是回显请求 */
case ICMP_ECHO:
/* 先检查目的IP地址是否合法 */
#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING
{
/* accepted表示是否对ICMP回显请求进行回应 */
int accepted = 1;
#if !LWIP_MULTICAST_PING
/* multicast destination address? */
/* 如果目的IP地址是多播地址,则不回应 */
if (ip_addr_ismulticast(&iphdr->dest)) {
accepted = 0;
}
#endif /* LWIP_MULTICAST_PING */
#if !LWIP_BROADCAST_PING
/* broadcast destination address? */
/* 如果目的IP地址是广播地址,则不回应 */
if (ip_addr_isbroadcast(&iphdr->dest, inp)) {
accepted = 0;
}
#endif /* LWIP_BROADCAST_PING */
/* broadcast or multicast destination address not acceptd? */
/* 如果不回应,则释放pbuf后,返回 */
if (!accepted) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n"));
ICMP_STATS_INC(icmp.err);
pbuf_free(p);
return;
}
}
#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
/* 检查ICMP报文长度是否合法,ICMP报文总长度不能小于ICMP报头长度8字节 */
if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
/* 跳到lenerr处执行返回操作 */
goto lenerr;
}
/* 计算ICMP的校验和是否正确 */
if (inet_chksum_pbuf(p) != 0) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
/* ICMP校验和错误,则释放pbuf,并返回 */
pbuf_free(p);
ICMP_STATS_INC(icmp.chkerr);
snmp_inc_icmpinerrors();
return;
}
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
/* p is not big enough to contain link headers
* allocate a new one and copy p into it
*/
struct pbuf *r;
/* switch p->payload to ip header */
if (pbuf_header(p, hlen)) {
LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0);
goto memerr;
}
/* allocate new packet buffer with space for link headers */
r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
if (r == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
goto memerr;
}
//.........这里部分代码省略.........
示例14: ip_frag
/**
* Fragment an IP datagram if too large for the netif.
*
* Chop the datagram in MTU sized chunks and send them in order
* by using a fixed size static memory buffer (PBUF_REF) or
* point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF).
*
* @param p ip packet to send
* @param netif the netif on which to send
* @param dest destination ip address to which to send
*
* @return ERR_OK if sent successfully, err_t otherwise
*/
err_t
ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest)
{
struct pbuf *rambuf;
#if IP_FRAG_USES_STATIC_BUF
struct pbuf *header;
#else
#if !LWIP_NETIF_TX_SINGLE_PBUF
struct pbuf *newpbuf;
#endif
struct ip_hdr *original_iphdr;
#endif
struct ip_hdr *iphdr;
u16_t nfb;
u16_t left, cop;
u16_t mtu = netif->mtu;
u16_t ofo, omf;
u16_t last;
u16_t poff = IP_HLEN;
u16_t tmp;
#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF
u16_t newpbuflen = 0;
u16_t left_to_copy;
#endif
/* Get a RAM based MTU sized pbuf */
#if IP_FRAG_USES_STATIC_BUF
/* When using a static buffer, we use a PBUF_REF, which we will
* use to reference the packet (without link header).
* Layer and length is irrelevant.
*/
rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF);
if (rambuf == NULL) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n"));
return ERR_MEM;
}
rambuf->tot_len = rambuf->len = mtu;
rambuf->payload = LWIP_MEM_ALIGN((void *)buf);
/* Copy the IP header in it */
iphdr = (struct ip_hdr *)rambuf->payload;
SMEMCPY(iphdr, p->payload, IP_HLEN);
#else /* IP_FRAG_USES_STATIC_BUF */
original_iphdr = (struct ip_hdr *)p->payload;
iphdr = original_iphdr;
#endif /* IP_FRAG_USES_STATIC_BUF */
/* Save original offset */
tmp = ntohs(IPH_OFFSET(iphdr));
ofo = tmp & IP_OFFMASK;
omf = tmp & IP_MF;
left = p->tot_len - IP_HLEN;
nfb = (mtu - IP_HLEN) / 8;
while (left) {
last = (left <= mtu - IP_HLEN);
/* Set new offset and MF flag */
tmp = omf | (IP_OFFMASK & (ofo));
if (!last) {
tmp = tmp | IP_MF;
}
/* Fill this fragment */
cop = last ? left : nfb * 8;
#if IP_FRAG_USES_STATIC_BUF
poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff);
#else /* IP_FRAG_USES_STATIC_BUF */
#if LWIP_NETIF_TX_SINGLE_PBUF
rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM);
if (rambuf == NULL) {
return ERR_MEM;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
poff += pbuf_copy_partial(p, rambuf->payload, cop, poff);
/* make room for the IP header */
if(pbuf_header(rambuf, IP_HLEN)) {
pbuf_free(rambuf);
return ERR_MEM;
}
/* fill in the IP header */
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = rambuf->payload;
//.........这里部分代码省略.........
示例15: icmp_input
/**
* Processes ICMP input packets, called from ip_input().
*
* Currently only processes icmp echo requests and sends
* out the echo response.
*
* @param p the icmp echo request packet, p->payload pointing to the ip header
* @param inp the netif on which this packet was received
*/
void
icmp_input(struct pbuf *p, struct netif *inp)
{
u8_t type;
#ifdef LWIP_DEBUG
u8_t code;
#endif /* LWIP_DEBUG */
struct icmp_echo_hdr *iecho;
struct ip_hdr *iphdr;
struct ip_addr tmpaddr;
s16_t hlen;
ICMP_STATS_INC(icmp.recv);
snmp_inc_icmpinmsgs();
iphdr = p->payload;
hlen = IPH_HL(iphdr) * 4;
if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
goto lenerr;
}
type = *((u8_t *)p->payload);
#ifdef LWIP_DEBUG
code = *(((u8_t *)p->payload)+1);
#endif /* LWIP_DEBUG */
switch (type) {
case ICMP_ECHO:
/* broadcast or multicast destination address? */
if (ip_addr_isbroadcast(&iphdr->dest, inp) || ip_addr_ismulticast(&iphdr->dest)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n"));
ICMP_STATS_INC(icmp.err);
pbuf_free(p);
return;
}
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
goto lenerr;
}
if (inet_chksum_pbuf(p) != 0) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
pbuf_free(p);
ICMP_STATS_INC(icmp.chkerr);
snmp_inc_icmpinerrors();
return;
}
if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
/* p is not big enough to contain link headers
* allocate a new one and copy p into it
*/
struct pbuf *r;
/* switch p->payload to ip header */
if (pbuf_header(p, hlen)) {
LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0);
goto memerr;
}
/* allocate new packet buffer with space for link headers */
r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
if (r == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
goto memerr;
}
LWIP_ASSERT("check that first pbuf can hold struct the ICMP header",
(r->len >= hlen + sizeof(struct icmp_echo_hdr)));
/* copy the whole packet including ip header */
if (pbuf_copy(r, p) != ERR_OK) {
LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0);
goto memerr;
}
iphdr = r->payload;
/* switch r->payload back to icmp header */
if (pbuf_header(r, -hlen)) {
LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
goto memerr;
}
/* free the original p */
pbuf_free(p);
/* we now have an identical copy of p that has room for link headers */
p = r;
} else {
/* restore p->payload to point to icmp header */
if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
goto memerr;
}
}
/* At this point, all checks are OK. */
/* We generate an answer by switching the dest and src ip addresses,
* setting the icmp type to ECHO_RESPONSE and updating the checksum. */
//.........这里部分代码省略.........