static struct altcp_pcb* smtp_setup_pcb(struct smtp_session *s, const ip_addr_t* remote_ip) { struct altcp_pcb* pcb; LWIP_UNUSED_ARG(remote_ip); #if LWIP_ALTCP && LWIP_ALTCP_TLS if (smtp_server_tls_config) { pcb = altcp_tls_new(smtp_server_tls_config, IP_GET_TYPE(remote_ip)); } else #endif { pcb = altcp_tcp_new_ip_type(IP_GET_TYPE(remote_ip)); } if (pcb != NULL) { altcp_arg(pcb, s); altcp_recv(pcb, smtp_tcp_recv); altcp_err(pcb, smtp_tcp_err); altcp_poll(pcb, smtp_tcp_poll, SMTP_POLL_INTERVAL); altcp_sent(pcb, smtp_tcp_sent); } return pcb; }
/** * @ingroup raw_raw * 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, const ip_addr_t *ipaddr) { err_t err; struct netif *netif; const ip_addr_t *src_ip; struct pbuf *q; /* q will be sent down the stack */ s16_t header_size; if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) { return ERR_VAL; } LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); header_size = ( #if LWIP_IPV4 && LWIP_IPV6 IP_IS_V6(ipaddr) ? IP6_HLEN : IP_HLEN); #elif LWIP_IPV4 IP_HLEN); #else IP6_HLEN); #endif /* not enough space to add an IP header to first pbuf in given p chain? */ if (pbuf_header(p, header_size)) { /* 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, -header_size)) { LWIP_ASSERT("Can't restore header we just removed!", 0); return ERR_MEM; } } if(IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { /* Don't call ip_route() with IP_ANY_TYPE */ netif = ip_route(IP46_ADDR_ANY(IP_GET_TYPE(ipaddr)), ipaddr, pcb->interface_name); } else { netif = ip_route(&pcb->local_ip, ipaddr, pcb->interface_name); } if (netif == NULL) { LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ipaddr); /* free any temporary header pbuf allocated by pbuf_header() */ if (q != p) { pbuf_free(q); } return ERR_RTE; } #if IP_SOF_BROADCAST if (IP_IS_V4(ipaddr)) { /* 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 = ip_netif_get_local_ip(netif, ipaddr); #if LWIP_IPV6 if (src_ip == NULL) { if (q != p) { pbuf_free(q); } return ERR_RTE; } #endif /* LWIP_IPV6 */ } else { /* use RAW PCB local IP address as source address */ src_ip = &pcb->local_ip; } #if LWIP_IPV6 /* If requested, based on the IPV6_CHECKSUM socket option per RFC3542, compute the checksum and update the checksum in the payload. */ if (IP_IS_V6(ipaddr) && pcb->chksum_reqd) { u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ip_2_ip6(src_ip), ip_2_ip6(ipaddr)); LWIP_ASSERT("Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2)); SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum, sizeof(u16_t)); } #endif 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; }