/** * Function: checkConnectionExist * Description: 检测要建立的连接是否已经存在,如果存在则直接返回存在的连接 * @param local_ip 客户端的IP地址 * @param local_port 客户端的端口号 * @param remote_ip 连接的远程主机的IP地址 * @param remote_port 远程主机的端口号 * @return 连接存在返回连接的PCB * 连接不存在返回NULL **/ static struct tcp_pcb* checkConnectionExist(ip_addr_t *local_ip,u16_t local_port,ip_addr_t remote_ip,u16_t remote_port) { struct tcp_pcb *cpcb; int i; ip_addr_t temp_ip; if (ip_addr_isany(local_ip)) { /* no local IP address set, yet. */ struct netif *netif = ip_route(local_ip); if (netif == NULL) { return NULL; } /* Use the netif's IP address as local address. */ ip_addr_copy(temp_ip, netif->ip_addr); } else { ip_addr_copy(temp_ip, *local_ip); } /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { if (cpcb->local_port == local_port) { if((cpcb->remote_port == remote_port) && ip_addr_cmp(&cpcb->local_ip, &temp_ip) && ip_addr_cmp(&cpcb->remote_ip,&remote_ip)) { return cpcb; } } } } return NULL; }
rn_link * getroute(ip_state * state, rn_message * msg, tw_lp * lp) { rn_machine *me = rn_getmachine(lp->gid); rn_link *link = NULL; //int next_hop = -1; /* * Get the next_hop destination from the forwarding table * for this IP packet. */ if(msg->src == lp->gid && me->nlinks == 1) link = me->link; else if(NULL == (link = ip_route(me, msg))) link = rn_getlink(me, msg->dst); if(NULL == link) { state->stats->s_nnet_failures++; ip_packet_drop(state, msg, lp); return NULL; } return link; }
/*-----------------------------------------------------------------------------------*/ static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) { u16_t len, tot_len; struct netif *netif; /* The TCP header has already been constructed, but the ackno and wnd fields remain. */ seg->tcphdr->ackno = htonl(pcb->rcv_nxt); /* silly window avoidance */ if(pcb->rcv_wnd < pcb->mss) { seg->tcphdr->wnd = 0; } else { seg->tcphdr->wnd = htons(pcb->rcv_wnd); } /* If we don't have a local IP address, we get one by calling ip_route(). */ if(ip_addr_isany(&(pcb->local_ip))) { netif = ip_route(&(pcb->remote_ip)); if(netif == NULL) { return; } ip_addr_set(&(pcb->local_ip), &(netif->ip_addr)); } pcb->rtime = 0; if(pcb->rttest == 0) { pcb->rttest = tcp_ticks; pcb->rtseq = ntohl(seg->tcphdr->seqno); DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %lu\n", pcb->rtseq)); } DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %lu:%lu\n", htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + seg->len)); seg->tcphdr->chksum = 0; #if CHECKSUM_GEN_TCP seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), &(pcb->remote_ip), IP_PROTO_TCP, seg->p->tot_len); #endif #ifdef TCP_STATS ++stats.tcp.xmit; #endif /* TCP_STATS */ len = seg->p->len; tot_len = seg->p->tot_len; ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL, IP_PROTO_TCP); seg->p->len = len; seg->p->tot_len = tot_len; seg->p->payload = seg->tcphdr; }
/*-----------------------------------------------------------------------------------*/ void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg) { u32_t wnd; u16_t len, tot_len; struct netif *netif; DEBUGF(TCP_REXMIT_DEBUG, ("tcp_rexmit_seg: skickar %ld:%ld\n", ntohl(seg->tcphdr->seqno), ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); wnd = MIN(pcb->snd_wnd, pcb->cwnd); if(ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { /* Count the number of retranmissions. */ ++pcb->nrtx; if((netif = ip_route((struct ip_addr *)&(pcb->remote_ip))) == NULL) { DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_rexmit_segment: No route to 0x%lx\n", pcb->remote_ip.addr)); #ifdef TCP_STATS ++stats.tcp.rterr; #endif /* TCP_STATS */ return; } seg->tcphdr->ackno = htonl(pcb->rcv_nxt); seg->tcphdr->wnd = htons(pcb->rcv_wnd); /* Recalculate checksum. */ seg->tcphdr->chksum = 0; #if CHECKSUM_GEN_TCP seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), &(pcb->remote_ip), IP_PROTO_TCP, seg->p->tot_len); #endif len = seg->p->len; tot_len = seg->p->tot_len; pbuf_header(seg->p, IP_HLEN); ip_output_if(seg->p, NULL, IP_HDRINCL, TCP_TTL, IP_PROTO_TCP, netif); seg->p->len = len; seg->p->tot_len = tot_len; seg->p->payload = seg->tcphdr; #ifdef TCP_STATS ++stats.tcp.xmit; ++stats.tcp.rexmit; #endif /* TCP_STATS */ pcb->rtime = 0; /* Don't take any rtt measurements after retransmitting. */ pcb->rttest = 0; } else { DEBUGF(TCP_REXMIT_DEBUG, ("tcp_rexmit_seg: no room in window %lu to send %lu (ack %lu)\n", wnd, ntohl(seg->tcphdr->seqno), pcb->lastack)); } }
/** * Actually send a TCP segment over IP */ static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) { u16_t len; struct netif *netif; /* The TCP header has already been constructed, but the ackno and wnd fields remain. */ seg->tcphdr->ackno = htonl(pcb->rcv_nxt); /* silly window avoidance */ if (pcb->rcv_wnd < pcb->mss) { seg->tcphdr->wnd = 0; } else { /* advertise our receive window size in this TCP segment */ seg->tcphdr->wnd = htons(pcb->rcv_wnd); } /* If we don't have a local IP address, we get one by calling ip_route(). */ if (ip_addr_isany(&(pcb->local_ip))) { netif = ip_route(&(pcb->remote_ip)); if (netif == NULL) { return; } ip_addr_set(&(pcb->local_ip), &(netif->ip_addr)); } pcb->rtime = 0; if (pcb->rttest == 0) { pcb->rttest = tcp_ticks; pcb->rtseq = ntohl(seg->tcphdr->seqno); LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); } LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + seg->len)); len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); seg->p->len -= len; seg->p->tot_len -= len; seg->p->payload = seg->tcphdr; seg->tcphdr->chksum = 0; #if CHECKSUM_GEN_TCP seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), &(pcb->remote_ip), IP_PROTO_TCP, seg->p->tot_len); #endif TCP_STATS_INC(tcp.xmit); ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, IP_PROTO_TCP); }
/** * Sends an generic or enterprise specific trap message. * * @param generic_trap is the trap code * @param eoid points to enterprise object identifier * @param specific_trap used for enterprise traps when generic_trap == 6 * @return ERR_OK when success, ERR_MEM if we're out of memory * * @note the caller is responsible for filling in outvb in the trap_msg * @note the use of the enterpise identifier field * is per RFC1215. * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps * and .iso.org.dod.internet.private.enterprises.yourenterprise * (sysObjectID) for specific traps. */ err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) { struct snmp_trap_dst *td; struct netif *dst_if; ip_addr_t dst_ip; struct pbuf *p; u16_t i,tot_len; for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++) { if ((td->enable != 0) && !ip_addr_isany(&td->dip)) { /* network order trap destination */ ip_addr_copy(trap_msg.dip, td->dip); /* lookup current source address for this dst */ dst_if = ip_route(&td->dip); ip_addr_copy(dst_ip, dst_if->ip_addr); /* @todo: what about IPv6? */ trap_msg.sip_raw[0] = ip4_addr1(&dst_ip); trap_msg.sip_raw[1] = ip4_addr2(&dst_ip); trap_msg.sip_raw[2] = ip4_addr3(&dst_ip); trap_msg.sip_raw[3] = ip4_addr4(&dst_ip); trap_msg.gen_trap = generic_trap; trap_msg.spc_trap = specific_trap; if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) { /* enterprise-Specific trap */ trap_msg.enterprise = eoid; } else { /* generic (MIB-II) trap */ snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); } snmp_get_sysuptime(&trap_msg.ts); /* pass 0, calculate length fields */ tot_len = snmp_varbind_list_sum(&trap_msg.outvb); tot_len = snmp_trap_header_sum(&trap_msg, tot_len); /* allocate pbuf(s) */ p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); if (p != NULL) { u16_t ofs; /* pass 1, encode packet ino the pbuf(s) */ ofs = snmp_trap_header_enc(&trap_msg, p); snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); snmp_inc_snmpouttraps(); snmp_inc_snmpoutpkts(); /** send to the TRAP destination */ udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT); pbuf_free(p); } else { return ERR_MEM; } } } return ERR_OK; }
/** * Send the raw IP packet to the given address. Note that actually you cannot * modify the IP headers (this is inconsitent with the receive callback where * you actually get the IP headers), you can only specifiy 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 whole IP packet * */ err_t raw_send_to(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr) { err_t err; struct netif *netif; struct ip_addr *src_ip; struct pbuf *q; /* q will be sent down the stack */ LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_send_to\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 | DBG_TRACE | 2, ("raw_send_to: could not allocate header\n")); return ERR_MEM; } /* 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_send_to: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); } else { /* first pbuf q equals given pbuf */ q = p; pbuf_header(q, -IP_HLEN); } if ((netif = ip_route(ipaddr)) == NULL) { LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_send_to: No route to 0x%lx\n", ipaddr->addr)); #if RAW_STATS /* ++lwip_stats.raw.rterr;*/ #endif /* RAW_STATS */ if (q != p) { pbuf_free(q); } return ERR_RTE; } 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); } err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); /* did we chain a header earlier? */ if (q != p) { /* free the header */ pbuf_free(q); } return err; }
// remove MTD_FLASHMEM to speedup routing err_t MTD_FLASHMEM Router::netif_input(pbuf *p, netif *inp) { eth_hdr* ethdr = (eth_hdr*)p->payload; if (ntohs(ethdr->type) == ETHTYPE_IP) { // move buffer pointer to start of IP header pbuf_header(p, -sizeof(eth_hdr)); ip_hdr* iphdr = (ip_hdr*)(p->payload); // needs to route? // 1. check match of source interface IP/netmask and destination IP bool route = ((iphdr->dest.addr & inp->netmask.addr) != (inp->ip_addr.addr & inp->netmask.addr)); // 2. check if not multicast or broadcast (>=224.0.0.0 up to 255.255.255.255) route = route && ((iphdr->dest.addr & 0xE0) != 0xE0); if (route) { /* debug("netif_input intf=%d len=%d id=%d prot=%d src=%s dst=%s route?=%c\r\n", inp->num, p->tot_len, IPH_ID(iphdr), IPH_PROTO(iphdr), (char const*)IPAddress(iphdr->src.addr).get_str(), (char const*)IPAddress(iphdr->dest.addr).get_str(), route?'Y':'N'); */ // find destination interface ip_addr_t ipdest; ipdest.addr = iphdr->dest.addr; netif* destIntf = ip_route(&ipdest); // decrement TTL IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); if (IPH_TTL(iphdr) > 0) { // update IP checksum if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); else IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); // send the packet ip_output_if(p, NULL, IP_HDRINCL, 0, 0, 0, destIntf); } pbuf_free(p); return ERR_OK; } // restore buffer pointer to start of Ethernet header pbuf_header(p, +sizeof(eth_hdr)); } return (Router::s_prevInput[inp->num])(p, inp); }
err_t udp_send(struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, unsigned short dst_port, struct netif *netif) { struct udp_hdr *udphdr; struct ip_addr *src_ip; err_t err; if (!dst_ip) dst_ip = &pcb->remote_ip; if (ip_addr_isany(dst_ip)) return -EDESTADDRREQ; if (dst_port == 0) dst_port = pcb->remote_port; if (dst_port == 0) return -ENOTCONN; if (pbuf_header(p, UDP_HLEN) < 0) { kprintf(KERN_ERR "udp_send: not enough room for UDP header in pbuf\n"); stats.udp.err++; return -EBUF; } udphdr = p->payload; udphdr->src = htons(pcb->local_port); udphdr->dest = htons(dst_port); udphdr->chksum = 0x0000; if (netif == NULL) { if ((netif = ip_route(dst_ip)) == NULL) { kprintf(KERN_ERR "udp_send: No route to %a\n", dst_ip); stats.udp.rterr++; return -EROUTE; } } if (ip_addr_isbroadcast(dst_ip, &netif->netmask) && (pcb->flags & UDP_FLAGS_BROADCAST) == 0) return -EACCES; if (ip_addr_isany(&pcb->local_ip)) { src_ip = &netif->ipaddr; } else { src_ip = &pcb->local_ip; } //kprintf("udp_send: sending datagram of length %d\n", p->tot_len); udphdr->len = htons((unsigned short) p->tot_len); // Calculate checksum if ((netif->flags & NETIF_UDP_TX_CHECKSUM_OFFLOAD) == 0) { if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { udphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip, IP_PROTO_UDP, p->tot_len); if (udphdr->chksum == 0x0000) udphdr->chksum = 0xFFFF; } } //udp_debug_print(udphdr); err = ip_output_if(p, src_ip, dst_ip, UDP_TTL, IP_PROTO_UDP, netif); stats.udp.xmit++; return err; }
/** * Forwards an IP packet. It finds an appropriate route for the * packet, decrements the TTL value of the packet, adjusts the * checksum and outputs the packet on the appropriate interface. * * @param p the packet to forward (p->payload points to IP header) * @param iphdr the IP header of the input packet * @param inp the netif on which this packet was received * @return the netif on which the packet was sent (NULL if it wasn't sent) */ static struct netif * ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) { struct netif *netif; PERF_START; /* Find network interface where to forward this IP packet to. */ netif = ip_route((struct ip_addr *)&(iphdr->dest)); if (netif == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%"X32_F" found\n", iphdr->dest.addr)); snmp_inc_ipoutnoroutes(); return (struct netif *)NULL; } /* Do not forward packets onto the same network interface on which * they arrived. */ if (netif == inp) { LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); snmp_inc_ipoutnoroutes(); return (struct netif *)NULL; } /* decrement TTL */ IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); /* send ICMP if TTL == 0 */ if (IPH_TTL(iphdr) == 0) { snmp_inc_ipinhdrerrors(); #if LWIP_ICMP /* Don't send ICMP messages in response to ICMP messages */ if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { icmp_time_exceeded(p, ICMP_TE_TTL); } #endif /* LWIP_ICMP */ return (struct netif *)NULL; } /* Incrementally update the IP checksum. */ if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) { IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1); } else { IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100)); } LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%"X32_F"\n", iphdr->dest.addr)); IP_STATS_INC(ip.fw); IP_STATS_INC(ip.xmit); snmp_inc_ipforwdatagrams(); PERF_STOP("ip_forward"); /* transmit pbuf on chosen interface */ netif->output(netif, p, (struct ip_addr *)&(iphdr->dest)); return netif; }
rn_link * rc_getroute(ip_state * state, rn_message * msg, tw_lp * lp) { rn_machine *me = rn_getmachine(lp->gid); rn_link *link = NULL; /* * Get the next_hop destination from the forwarding table * for this IP packet. */ if(msg->src == lp->gid && me->nlinks == 1) link = me->link; else if(NULL == (link = ip_route(me, msg))) link = rn_getlink(me, msg->dst); #if 0 else if(NULL == (link = rn_getlink(me, msg->dst))) link = ip_route(me, msg); #endif return link; }
/** * Connect an UDP PCB. * * This will associate the UDP PCB with the remote address. * * @param pcb UDP PCB to be connected with remote address ipaddr and port. * @param ipaddr remote IP address to connect with. * @param port remote UDP port to connect with. * * @return lwIP error code * * ipaddr & port are expected to be in the same byte order as in the pcb. * * The udp pcb is bound to a random local port if not already bound. * * @see udp_disconnect() */ err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) { struct udp_pcb *ipcb; if (pcb->local_port == 0) { err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); if (err != ERR_OK) return err; } ip_addr_set(&pcb->remote_ip, ipaddr); pcb->remote_port = port; pcb->flags |= UDP_FLAGS_CONNECTED; /** TODO: this functionality belongs in upper layers */ #ifdef LWIP_UDP_TODO /* Nail down local IP for netconn_addr()/getsockname() */ if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) { struct netif *netif; if ((netif = ip_route(&(pcb->remote_ip))) == NULL) { LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr)); UDP_STATS_INC(udp.rterr); return ERR_RTE; } /** TODO: this will bind the udp pcb locally, to the interface which is used to route output packets to the remote address. However, we might want to accept incoming packets on any interface! */ pcb->local_ip = netif->ip_addr; } else if (ip_addr_isany(&pcb->remote_ip)) { pcb->local_ip.addr = 0; } #endif LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n", (u16_t)((ntohl(pcb->remote_ip.addr) >> 24) & 0xff), (u16_t)((ntohl(pcb->remote_ip.addr) >> 16) & 0xff), (u16_t)((ntohl(pcb->remote_ip.addr) >> 8) & 0xff), (u16_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port)); /* Insert UDP PCB into the list of active UDP PCBs. */ for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { if (pcb == ipcb) { /* already on the list, just return */ return ERR_OK; } } /* PCB not yet on the list, add PCB now */ pcb->next = udp_pcbs; udp_pcbs = pcb; return ERR_OK; }
/*-----------------------------------------------------------------------------------*/ static void ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) { static struct netif *netif; PERF_START; if((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) { DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n", iphdr->dest.addr)); return; } /* Don't forward packets onto the same network interface on which they arrived. */ if(netif == inp) { DEBUGF(IP_DEBUG, ("ip_forward: not forward packets back on incoming interface.\n")); return; } /* Decrement TTL and send ICMP if ttl == 0. */ IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); if(IPH_TTL(iphdr) == 0) { /* Don't send ICMP messages in response to ICMP messages */ if(IPH_PROTO(iphdr) != IP_PROTO_ICMP) { icmp_time_exceeded(p, ICMP_TE_TTL); } return; } /* Incremental update of the IP checksum. */ if(IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) { IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1); } else { IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100)); } DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n", iphdr->dest.addr)); #ifdef IP_STATS ++stats.ip.fw; ++stats.ip.xmit; #endif /* IP_STATS */ PERF_STOP("ip_forward"); netif->output(netif, p, (struct ip_addr *)&(iphdr->dest)); }
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto) { struct netif *netif; if ((netif = ip_route(dest)) == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); IP_STATS_INC(ip.rterr); return ERR_RTE; } return ip_output_if (p, src, dest, ttl, proto, netif); }
/** * Simple interface to ip_output_if. It finds the outgoing network * interface and calls upon ip_output_if to do the actual work. * * @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 * * @return ERR_RTE if no route is found * see ip_output_if() for more return values */ uint8 ip_output(PBUF *p, IP_ADDR *src, IP_ADDR *dest, uint8 ttl, uint8 tos, uint8 proto) { NETIF *netif; netif = ip_route(dest); { TCP_HDR *tcphdr; tcphdr = (TCP_HDR *)p->payload; //printf("fle-->send: seq=%010u nxt:%010u len:%3u wnd:%u\n", ntohl(tcphdr->seqno), ntohl(tcphdr->ackno), p->tcplen, ntohs(tcphdr->wnd)); } return ip_output_if(p, src, dest, ttl, tos, proto, netif); }
static FlowMan_RouteInfo *ActiveRoute_m( FlowMan_cl *self, const FlowMan_SAP *rsap) { flowman_st *st = (flowman_st *) self->st; /* We currently don't route ATM SAPs */ if (rsap->tag != FlowMan_PT_TCP && rsap->tag != FlowMan_PT_UDP) RAISE_FlowMan$NoRoute(); return ip_route(st->host->routetab, rsap->u.UDP.addr.a, 0); }
static void ip_forward(struct pbuf *p, struct ip_hdr *iphdr) { struct netif *netif; PERF_START; if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for ")); #if IP_DEBUG ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); #endif /* IP_DEBUG */ LWIP_DEBUGF(IP_DEBUG, ("\n")); pbuf_free(p); return; } /* Decrement TTL and send ICMP if ttl == 0. */ if (--iphdr->hoplim == 0) { #if LWIP_ICMP /* Don't send ICMP messages in response to ICMP messages */ if (iphdr->nexthdr != IP_PROTO_ICMP) { icmp_time_exceeded(p, ICMP_TE_TTL); } #endif /* LWIP_ICMP */ pbuf_free(p); return; } /* Incremental update of the IP checksum. */ /* if (iphdr->chksum >= htons(0xffff - 0x100)) { iphdr->chksum += htons(0x100) + 1; } else { iphdr->chksum += htons(0x100); }*/ LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to ")); #if IP_DEBUG ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); #endif /* IP_DEBUG */ LWIP_DEBUGF(IP_DEBUG, ("\n")); IP_STATS_INC(ip.fw); IP_STATS_INC(ip.xmit); PERF_STOP("ip_forward"); netif->output(netif, p, (struct ip_addr *)&(iphdr->dest)); }
/** * Send data to a specified address using UDP. * * @param pcb UDP PCB used to send the data. * @param p chain of pbuf's to be sent. * @param dst_ip Destination IP address. * @param dst_port Destination UDP port. * * dst_ip & dst_port are expected to be in the same byte order as in the pcb. * * If the PCB already has a remote address association, it will * be restored after the data is sent. * * @return lwIP error code (@see udp_send for possible error codes) * * @see udp_disconnect() udp_send() */ err_t udp_sendto(struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port) { struct netif *netif; LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); /* find the outgoing network interface for this packet */ #if LWIP_IGMP netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip)); #else netif = ip_route(dst_ip); #endif /* LWIP_IGMP */ /* no outgoing network interface could be found? */ if (netif == NULL) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to 0x%"X32_F"\n", dst_ip->addr)); UDP_STATS_INC(udp.rterr); return ERR_RTE; } return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); }
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto) { struct netif *netif; if ((netif = ip_route(dest)) == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); #ifdef IP_STATS ++lwip_stats.ip.rterr; #endif /* IP_STATS */ return ERR_RTE; } return ip_output_if (p, src, dest, ttl, proto, netif); }
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t tos, u8_t proto) { struct netif *netif; if ((netif = ip_route(dest)) == NULL) { LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr)); IP_STATS_INC(ip.rterr); snmp_inc_ipoutdiscards(); return ERR_RTE; } return ip_output_if(p, src, dest, ttl, tos, proto, netif); }
/** Add a new static entry to the ARP table. If an entry exists for the * specified IP address, this entry is overwritten. * If packets are queued for the specified IP address, they are sent out. * * @param ipaddr IP address for the new static entry * @param ethaddr ethernet address for the new static entry * @return @see return values of etharp_add_static_entry */ err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr) { struct netif *netif; LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); netif = ip_route(ipaddr); if (netif == NULL) { return ERR_RTE; } return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); }
err_t ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) { struct netif *netif; err_t err; if ((netif = ip_route(dest)) == NULL) { LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); IP_STATS_INC(ip.rterr); return ERR_RTE; } netif->addr_hint = addr_hint; err = ip_output_if(p, src, dest, ttl, tos, proto, netif); netif->addr_hint = NULL; return err; }
static void refresh_cache(struct ip_addr *dst_ip) { struct netif *netif; netif = ip_route(dst_ip); errval_t r = etharp_request(netif, dst_ip); assert(err_is_ok(r)); while (is_ip_present_in_arp_cache(dst_ip) == false) { r = event_dispatch(ws); if (err_is_fail(r)) { DEBUG_ERR(r, "in event_dispatch"); abort(); } } // end while: till arp not present }
/** * Mapping from loopback to local network for inbound (port-forwarded) * connections. * * Copy "src" to "dst" with ip_addr_set(dst, src), but if "src" is a * host's loopback address, copy local network address that maps it to * "dst". */ int pxremap_inbound_ip4(ip_addr_t *dst, ip_addr_t *src) { struct netif *netif; const struct ip4_lomap *lomap; unsigned int i; if (ip4_addr1(src) != IP_LOOPBACKNET) { ip_addr_set(dst, src); return PXREMAP_ASIS; } if (g_proxy_options->lomap_desc == NULL) { return PXREMAP_FAILED; } #if 0 /* ?TODO: with multiple interfaces we need to consider fwspec::dst */ netif = ip_route(target); if (netif == NULL) { return PXREMAP_FAILED; } #else netif = netif_list; LWIP_ASSERT1(netif != NULL); LWIP_ASSERT1(netif->next == NULL); #endif lomap = g_proxy_options->lomap_desc->lomap; for (i = 0; i < g_proxy_options->lomap_desc->num_lomap; ++i) { if (ip_addr_cmp(src, &lomap[i].loaddr)) { ip_addr_t net; ip_addr_get_network(&net, &netif->ip_addr, &netif->netmask); ip4_addr_set_u32(dst, htonl(ntohl(ip4_addr_get_u32(&net)) + lomap[i].off)); return PXREMAP_MAPPED; } } return PXREMAP_FAILED; }
static void ARP_m ( FlowMan_cl *self, uint32_t ipaddr /* IN */, Net_EtherAddr *hwaddr /* OUT */) { flowman_st *st = (flowman_st *) self->st; FlowMan_RouteInfo *ri; intf_st *ifst; char buf[20]; Net_EtherAddrP NOCLOBBER ret = NULL; /* route the IP address to see which interface we ARP out of */ ri = ip_route(st->host->routetab, ipaddr, 0); TRY { ifst = ifname2ifst(st->host, ri->ifname); if (!ifst) { printf("ARP: interface not found, can't happen\n"); RAISE_FlowMan$NoRoute(); } sprintf(buf, "Eth10:%08x", ipaddr); /* NB: raises Context$NotFound() if ARP fails => ok (see Flowman.if) */ ret = NAME_LOOKUP(buf, ifst->card->arper, Net_EtherAddrP); } FINALLY { free(ri->type); free(ri->ifname); free(ri); } ENDTRY; TRC(printf("FlowMan$ARP: ARP for %x returning " "%02x:%02x:%02x:%02x:%02x:%02x\n", ntohl(ipaddr), ret->a[0], ret->a[1], ret->a[2], ret->a[3], ret->a[4], ret->a[5])); memcpy(hwaddr, ret, sizeof(*hwaddr)); }
void show_route(char *arg) { ip_t dest; memset(&dest, 0, sizeof(ip_t)); dest = parse_ip(arg, NO_NETMASK); if (dest.family == 0) return; ip_route(&dest, NULL, RTM_GET, RTF_UP); /* * ip_route() calls rtmsg() which calls * print_getmsg() on RTM_GET to show a route, * so nothing else needs to happen here... */ return; }
int ip(char * Buffer,struct Global *g ) { int rc ; char arg0[80],arg1[80],arg2[80],arg3[80],arg4[80] ; bzero(arg1,sizeof(arg1)); bzero(arg2,sizeof(arg2)); bzero(arg3,sizeof(arg3)); sscanf(Buffer,"%s %s %s\n",arg1,arg2,arg3 ) ; if (!strcmp(arg2,"address") ) rc = ip_address(Buffer,g) ; else if (!strcmp(arg2,"route") ) rc = ip_route( Buffer, g) ; else { fprintf(stderr,"Erreur de syntaxe arg 2 ou arg3 \n" ) ; printf("Erreur de syntaxe arg 2 ou arg3\n") ; rc = 0 ; } return (rc) ; }
/** * Sends an generic or enterprise specific trap message. * * @param generic_trap is the trap code * @param eoid points to enterprise object identifier * @param specific_trap used for enterprise traps when generic_trap == 6 * @return ERR_OK when success, ERR_MEM if we're out of memory * * @note the caller is responsible for filling in outvb in the trap_msg * @note the use of the enterpise identifier field * is per RFC1215. * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps * and .iso.org.dod.internet.private.enterprises.yourenterprise * (sysObjectID) for specific traps. */ err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) { struct snmp_trap_dst *td; struct netif *dst_if; ip_addr_t dst_ip; struct pbuf *p; u16_t i,tot_len; for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++) { if ((td->enable != 0) && !ip_addr_isany(&td->dip)) { /* network order trap destination */ ip_addr_copy(trap_msg.dip, td->dip); /* lookup current source address for this dst */ dst_if = ip_route(&td->dip); ip_addr_copy(dst_ip, dst_if->ip_addr); /* @todo: what about IPv6? */ trap_msg.sip_raw[0] = ip4_addr1(&dst_ip); trap_msg.sip_raw[1] = ip4_addr2(&dst_ip); trap_msg.sip_raw[2] = ip4_addr3(&dst_ip); trap_msg.sip_raw[3] =
int WiFiClient::connect(IPAddress ip, uint16_t port) { ip_addr_t addr; addr.addr = ip; if (_client) stop(); // if the default interface is down, tcp_connect exits early without // ever calling tcp_err // http://lists.gnu.org/archive/html/lwip-devel/2010-05/msg00001.html netif* interface = ip_route(&addr); if (!interface) { DEBUGV("no route to host\r\n"); return 0; } tcp_pcb* pcb = tcp_new(); if (!pcb) return 0; if (_localPort > 0) { pcb->local_port = _localPort++; } tcp_arg(pcb, this); tcp_err(pcb, &WiFiClient::_s_err); tcp_connect(pcb, &addr, port, reinterpret_cast<tcp_connected_fn>(&WiFiClient::_s_connected)); esp_yield(); if (_client) return 1; // if tcp_error was called, pcb has already been destroyed. // tcp_abort(pcb); return 0; }
bool AsyncClient::connect(IPAddress ip, uint16_t port){ ip_addr_t addr; addr.addr = ip; if (_pcb){ return false; } netif* interface = ip_route(&addr); if (!interface){ return false; } tcp_pcb* pcb = tcp_new(); if (!pcb) return false; pcb->local_port = _localPort++; tcp_arg(pcb, this); tcp_err(pcb, &_s_error); tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected); return true; }