Exemplo n.º 1
0
void
netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
{
  ip_addr_set(&(netif->netmask), netmask);
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1(&netif->netmask),
    ip4_addr2(&netif->netmask),
    ip4_addr3(&netif->netmask),
    ip4_addr4(&netif->netmask)));
}
Exemplo n.º 2
0
/**
 * Change the default gateway for a network interface
 *
 * @param netif the network interface to change
 * @param gw the new default gateway
 *
 * @note call netif_set_addr() if you also want to change ip address and netmask
 */
void
netif_set_gw(struct netif *netif, struct ip_addr *gw)
{
  ip_addr_set(&(netif->gw), gw);
  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1(&netif->gw),
    ip4_addr2(&netif->gw),
    ip4_addr3(&netif->gw),
    ip4_addr4(&netif->gw)));
}
void
ip_debug_print(struct pbuf *p)
{
  struct ip_hdr *iphdr = p->payload;
  u8_t *payload;

  payload = (u8_t *)iphdr + IP_HLEN;

  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",
                    IPH_V(iphdr),
                    IPH_HL(iphdr),
                    IPH_TOS(iphdr),
                    ntohs(IPH_LEN(iphdr))));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",
                    ntohs(IPH_ID(iphdr)),
                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",
                    IPH_TTL(iphdr),
                    IPH_PROTO(iphdr),
                    ntohs(IPH_CHKSUM(iphdr))));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",
                    ip4_addr1(&iphdr->src),
                    ip4_addr2(&iphdr->src),
                    ip4_addr3(&iphdr->src),
                    ip4_addr4(&iphdr->src)));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",
                    ip4_addr1(&iphdr->dest),
                    ip4_addr2(&iphdr->dest),
                    ip4_addr3(&iphdr->dest),
                    ip4_addr4(&iphdr->dest)));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
}
Exemplo n.º 4
0
void
netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
{
  /* TODO: Handling of obsolete pcbs */
  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
#if LWIP_TCP
  struct tcp_pcb *pcb;
  struct tcp_pcb_listen *lpcb;

  /* address is actually being changed? */
  if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
  {
    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
    LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
    pcb = tcp_active_pcbs;
    while (pcb != NULL) {
      /* PCB bound to current local interface address? */
      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
        /* this connection must be aborted */
        struct tcp_pcb *next = pcb->next;
        LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
        tcp_abort(pcb);
        pcb = next;
      } else {
        pcb = pcb->next;
      }
    }
    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
      /* PCB bound to current local interface address? */
      if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
        /* The PCB is listening to the old ipaddr and
         * is set to listen to the new one instead */
        ip_addr_set(&(lpcb->local_ip), ipaddr);
      }
    }
  }
#endif
  ip_addr_set(&(netif->ip_addr), ipaddr);
#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */
  /** For Ethernet network interfaces, we would like to send a
   *  "gratuitous ARP"; this is an ARP packet sent by a node in order
   *  to spontaneously cause other nodes to update an entry in their
   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
   */ 
  etharp_query(netif, ipaddr, NULL);
#endif
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1(&netif->ip_addr),
    ip4_addr2(&netif->ip_addr),
    ip4_addr3(&netif->ip_addr),
    ip4_addr4(&netif->ip_addr)));
}
Exemplo n.º 5
0
/**
 * Change the IP address of a network interface
 *
 * @param netif the network interface to change
 * @param ipaddr the new IP address
 *
 * @note call netif_set_addr() if you also want to change netmask and
 * default gateway
 */
void
netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
{
  /* TODO: Handling of obsolete pcbs */
  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
#if LWIP_TCP
  struct tcp_pcb *pcb;
  struct tcp_pcb_listen *lpcb;

  /* address is actually being changed? */
  if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
  {
    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
    LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
    pcb = tcp_active_pcbs;
    while (pcb != NULL) {
      /* PCB bound to current local interface address? */
      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
        /* this connection must be aborted */
        struct tcp_pcb *next = pcb->next;
        LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
        tcp_abort(pcb);
        pcb = next;
      } else {
        pcb = pcb->next;
      }
    }
    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
      /* PCB bound to current local interface address? */
      if ((!(ip_addr_isany(&(lpcb->local_ip)))) &&
          (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) {
        /* The PCB is listening to the old ipaddr and
         * is set to listen to the new one instead */
        ip_addr_set(&(lpcb->local_ip), ipaddr);
      }
    }
  }
#endif
  snmp_delete_ipaddridx_tree(netif);
  snmp_delete_iprteidx_tree(0,netif);
  /* set new IP address to netif */
  ip_addr_set(&(netif->ip_addr), ipaddr);
  snmp_insert_ipaddridx_tree(netif);
  snmp_insert_iprteidx_tree(0,netif);

  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1(&netif->ip_addr),
    ip4_addr2(&netif->ip_addr),
    ip4_addr3(&netif->ip_addr),
    ip4_addr4(&netif->ip_addr)));
}
void wl_set_ipconfig(unsigned int ipaddr, unsigned int netmask, unsigned int gateway, unsigned int dnsserv)
{
	UserParam.cfg.IPCfg.Ip[0] = ip4_addr1(&ipaddr);
	UserParam.cfg.IPCfg.Ip[1] = ip4_addr2(&ipaddr);
	UserParam.cfg.IPCfg.Ip[2] = ip4_addr3(&ipaddr);
	UserParam.cfg.IPCfg.Ip[3] = ip4_addr4(&ipaddr);

	UserParam.cfg.IPCfg.Netmask[0] = ip4_addr1(&netmask);
	UserParam.cfg.IPCfg.Netmask[1] = ip4_addr2(&netmask);
	UserParam.cfg.IPCfg.Netmask[2] = ip4_addr3(&netmask);
	UserParam.cfg.IPCfg.Netmask[3] = ip4_addr4(&netmask);
	
	UserParam.cfg.IPCfg.GateWay[0] = ip4_addr1(&gateway);
	UserParam.cfg.IPCfg.GateWay[1] = ip4_addr2(&gateway);
	UserParam.cfg.IPCfg.GateWay[2] = ip4_addr3(&gateway);
	UserParam.cfg.IPCfg.GateWay[3] = ip4_addr4(&gateway);

	UserParam.cfg.IPCfg.Dns[0] = ip4_addr1(&dnsserv);
	UserParam.cfg.IPCfg.Dns[1] = ip4_addr2(&dnsserv);
	UserParam.cfg.IPCfg.Dns[2] = ip4_addr3(&dnsserv);
	UserParam.cfg.IPCfg.Dns[3] = ip4_addr4(&dnsserv);
}
Exemplo n.º 7
0
static void ICACHE_FLASH_ATTR captdnsRecv(void* arg, char *pusrdata, unsigned short length) {
	struct espconn *conn=(struct espconn *)arg;
#else
static void ICACHE_FLASH_ATTR captdnsRecv(struct sockaddr_in *premote_addr, char *pusrdata, unsigned short length) {
#endif
	char buff[DNS_LEN];
	char reply[DNS_LEN];
	int i;
	char *rend=&reply[length];
	char *p=pusrdata;
	DnsHeader *hdr=(DnsHeader*)p;
	DnsHeader *rhdr=(DnsHeader*)&reply[0];
	p+=sizeof(DnsHeader);
//	printf("DNS packet: id 0x%X flags 0x%X rcode 0x%X qcnt %d ancnt %d nscount %d arcount %d len %d\n", 
//		my_ntohs(&hdr->id), hdr->flags, hdr->rcode, my_ntohs(&hdr->qdcount), my_ntohs(&hdr->ancount), my_ntohs(&hdr->nscount), my_ntohs(&hdr->arcount), length);
	//Some sanity checks:
	if (length>DNS_LEN) return; 								//Packet is longer than DNS implementation allows
	if (length<sizeof(DnsHeader)) return; 						//Packet is too short
	if (hdr->ancount || hdr->nscount || hdr->arcount) return;	//this is a reply, don't know what to do with it
	if (hdr->flags&FLAG_TC) return;								//truncated, can't use this
	//Reply is basically the request plus the needed data
	memcpy(reply, pusrdata, length);
	rhdr->flags|=FLAG_QR;
	for (i=0; i<my_ntohs(&hdr->qdcount); i++) {
		//Grab the labels in the q string
		p=labelToStr(pusrdata, p, length, buff, sizeof(buff));
		if (p==NULL) return;
		DnsQuestionFooter *qf=(DnsQuestionFooter*)p;
		p+=sizeof(DnsQuestionFooter);
		printf("DNS: Q (type 0x%X class 0x%X) for %s\n", my_ntohs(&qf->type), my_ntohs(&qf->class), buff);
		if (my_ntohs(&qf->type)==QTYPE_A) {
			//They want to know the IPv4 address of something.
			//Build the response.
			rend=strToLabel(buff, rend, sizeof(reply)-(rend-reply)); //Add the label
			if (rend==NULL) return;
			DnsResourceFooter *rf=(DnsResourceFooter *)rend;
			rend+=sizeof(DnsResourceFooter);
			setn16(&rf->type, QTYPE_A);
			setn16(&rf->class, QCLASS_IN);
			setn32(&rf->ttl, 0);
			setn16(&rf->rdlength, 4); //IPv4 addr is 4 bytes;
			//Grab the current IP of the softap interface
			struct ip_info info;
			wifi_get_ip_info(SOFTAP_IF, &info);
			*rend++=ip4_addr1(&info.ip);
			*rend++=ip4_addr2(&info.ip);
			*rend++=ip4_addr3(&info.ip);
			*rend++=ip4_addr4(&info.ip);
			setn16(&rhdr->ancount, my_ntohs(&rhdr->ancount)+1);
//			printf("Added A rec to resp. Resp len is %d\n", (rend-reply));
		} else if (my_ntohs(&qf->type)==QTYPE_NS) {
Exemplo n.º 8
0
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
  struct tapif *tapif;
  char buf[100];

  tapif = netif->state;
  
  /* Obtain MAC address from network interface. */

  /* (We just fake an address...) */
  tapif->ethaddr->addr[0] = 0x1;
  tapif->ethaddr->addr[1] = 0x2;
  tapif->ethaddr->addr[2] = 0x3;
  tapif->ethaddr->addr[3] = 0x4;
  tapif->ethaddr->addr[4] = 0x5;
  tapif->ethaddr->addr[5] = 0x6;

  /* Do whatever else is needed to initialize interface. */
  
  tapif->fd = open(DEVTAP, O_RDWR);
  DEBUGF(TAPIF_DEBUG, ("tapif_init: fd %d\n", tapif->fd));
  if(tapif->fd == -1) {
    perror("tapif_init");
    exit(1);
  }

#ifdef linux
  {
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
    if (ioctl(tapif->fd, TUNSETIFF, (void *) &ifr) < 0) {
      perror(buf);
      exit(1);
    }
  }
#endif /* Linux */

  snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
           ip4_addr1(&(netif->gw)),
           ip4_addr2(&(netif->gw)),
           ip4_addr3(&(netif->gw)),
           ip4_addr4(&(netif->gw)));
  
  DEBUGF(TAPIF_DEBUG, ("tapif_init: system(\"%s\");\n", buf));
  system(buf);
//  sys_thread_new(tapif_thread, netif);

}
Exemplo n.º 9
0
static void uip_mcastmac(uip_ipaddr_t *ip, FAR uint8_t *mac)
{
  /* This mapping is from the IETF IN RFC 1700 */

  mac[0] = 0x01;
  mac[1] = 0x00;
  mac[2] = 0x5e;
  mac[3] = ip4_addr2(*ip) & 0x7f;
  mac[4] = ip4_addr3(*ip);
  mac[5] = ip4_addr4(*ip);

  nvdbg("IP: %08x -> MAC: %02x%02x%02x%02x%02x%02x\n",
        *ip, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
Exemplo n.º 10
0
/**
 * Change the netmask of a network interface
 *
 * @param netif the network interface to change
 * @param netmask the new netmask
 *
 * @note call netif_set_addr() if you also want to change ip address and
 * default gateway
 */
void
netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
{
  snmp_delete_iprteidx_tree(0, netif);
  /* set new netmask to netif */
  ip_addr_set(&(netif->netmask), netmask);
  snmp_insert_iprteidx_tree(0, netif);
  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1(&netif->netmask),
    ip4_addr2(&netif->netmask),
    ip4_addr3(&netif->netmask),
    ip4_addr4(&netif->netmask)));
}
Exemplo n.º 11
0
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
  struct mintapif *mintapif;
  char buf[1024];

  mintapif = netif->state;
  
  /* Obtain MAC address from network interface. */
  mintapif->ethaddr->addr[0] = 1;
  mintapif->ethaddr->addr[1] = 2;
  mintapif->ethaddr->addr[2] = 3;
  mintapif->ethaddr->addr[3] = 4;
  mintapif->ethaddr->addr[4] = 5;
  mintapif->ethaddr->addr[5] = 6;

  /* Do whatever else is needed to initialize interface. */  
  
  mintapif->fd = open(DEVTAP, O_RDWR);
  if (mintapif->fd == -1) {
    perror("tapif: tapif_init: open");
    exit(1);
  }

#ifdef linux
  {
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
    if (ioctl(mintapif->fd, TUNSETIFF, (void *) &ifr) < 0) {
      perror(buf);
      exit(1);
    }
  }
#endif /* Linux */

  snprintf(buf, sizeof(buf), "/sbin/ifconfig " IFCONFIG_ARGS,
           ip4_addr1(&(netif->gw)),
           ip4_addr2(&(netif->gw)),
           ip4_addr3(&(netif->gw)),
           ip4_addr4(&(netif->gw)));
  
  system(buf);

  mintapif->lasttime = 0;

}
Exemplo n.º 12
0
static void sys_net_status_changed(u8 status)
{
#if TLS_CONFIG_TLS_DEBUG
	struct tls_ethif * ethif;
#endif

    switch(status)
    {
        case NETIF_WIFI_JOIN_SUCCESS:
            TLS_DBGPRT_INFO("join net success\n");
            tls_sys_net_up();
            break;
	    case NETIF_WIFI_JOIN_FAILED:
            TLS_DBGPRT_INFO("join net failed\n");
		    tls_sys_connect_failed();
		    break;
        case NETIF_WIFI_DISCONNECTED:
            TLS_DBGPRT_INFO("net disconnected\n");
#if TLS_CONFIG_APSTA
            tls_sys_net2_down();
#endif
            tls_sys_net_down();
            break;
        case NETIF_IP_NET_UP:
#if TLS_CONFIG_TLS_DEBUG
			ethif = tls_netif_get_ethif();
            TLS_DBGPRT_INFO("net up ==> ip = %d.%d.%d.%d\n",ip4_addr1(&ethif->ip_addr.addr),ip4_addr2(&ethif->ip_addr.addr),
		                     ip4_addr3(&ethif->ip_addr.addr),ip4_addr4(&ethif->ip_addr.addr));
#endif
            break;
#if TLS_CONFIG_APSTA
        case NETIF_APSTA_STA_NET_UP:
            tls_sys_net2_up();
            break;
        case NETIF_WIFI_APSTA_STA_SUCCESS:
            TLS_DBGPRT_INFO("apsta 1/2 sta join net success\n");
            break;
        case NETIF_WIFI_APSTA_AP_SUCCESS:
            TLS_DBGPRT_INFO("apsta 2/2 ap  join net success\n");
            tls_sys_net_up();
            break;
#endif
        default:
            break;
    }
}
Exemplo n.º 13
0
err_t
prvxMBTCPPortAccept( void *pvArg, struct tcp_pcb *pxPCB, err_t xErr )
{
    err_t           error;

    if( xErr != ERR_OK )
    {
        return xErr;
    }

    /* We can handle only one client. */
    if( pxPCBClient == NULL )
    {
        /* Register the client. */
        pxPCBClient = pxPCB;

        /* Set up the receive function prvxMBTCPPortReceive( ) to be called when data
         * arrives.
         */
        tcp_recv( pxPCB, prvxMBTCPPortReceive );

        /* Register error handler. */
        tcp_err( pxPCB, prvvMBTCPPortError );

        /* Set callback argument later used in the error handler. */
        tcp_arg( pxPCB, pxPCB );

        /* Reset the buffers and state variables. */
        usTCPBufPos = 0;

#ifdef MB_TCP_DEBUG
        vMBPortLog( MB_LOG_DEBUG, "MBTCP-ACCEPT", "Accepted new client %d.%d.%d.%d\r\n",
                    ip4_addr1( &( pxPCB->remote_ip ) ),
                    ip4_addr2( &( pxPCB->remote_ip ) ),
                    ip4_addr3( &( pxPCB->remote_ip ) ), ip4_addr4( &( pxPCB->remote_ip ) ) );
#endif

        error = ERR_OK;
    }
    else
    {
        prvvMBPortReleaseClient( pxPCB );
        error = ERR_OK;
    }
    return error;
}
Exemplo n.º 14
0
/**
 * Initialize one of the NTP servers by IP address, required by DHCP
 *
 * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
 * @param dnsserver IP address of the NTP server to set
 */
void
dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
{
  LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
    (sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
    ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num));
  if (sntp_set_servers_from_dhcp && num) {
    u8_t i;
    for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) {
      ip_addr_t addr;
      ip_addr_copy_from_ip4(addr, server[i]);
      sntp_setserver(i, &addr);
    }
    for (i = num; i < SNTP_MAX_SERVERS; i++) {
      sntp_setserver(i, NULL);
    }
  }
}
Exemplo n.º 15
0
void lcd_ip_addr()
{
  /* Declare local ipaddr variable. */
  ip_addr* ipaddr;
  
  /* Assign ipaddr to the network interface's IP Address. 
   * NOTE:  This code assumes that only a single network
   * interface exists
   */
  ipaddr = &nets[0]->n_ipaddr;
  
  /* Display the IP Address (initially) on the LCD Display. */
  lcdDevice = fopen( "/dev/lcd", "w" ); 
  fprintf(lcdDevice, "\nIP Address\n%d.%d.%d.%d\n",
        ip4_addr1(*ipaddr),
        ip4_addr2(*ipaddr),
        ip4_addr3(*ipaddr),
        ip4_addr4(*ipaddr));
  fclose( lcdDevice );
}
void
tcp_keepalive(struct tcp_pcb *pcb)
{
   struct pbuf *p;
   struct tcp_hdr *tcphdr;

   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
                           ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
                           ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));

   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F"  pcb->keep_cnt %"U16_F"\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));
   
   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);

   if(p == NULL) {
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: could not allocate memory for pbuf\n"));
      return;
   }

   tcphdr = p->payload;
   tcphdr->src = htons(pcb->local_port);
   tcphdr->dest = htons(pcb->remote_port);
   tcphdr->seqno = htonl(pcb->snd_nxt - 1);
   tcphdr->ackno = htonl(pcb->rcv_nxt);
   tcphdr->wnd = htons(pcb->rcv_wnd);
   tcphdr->urgp = 0;
   TCPH_HDRLEN_SET(tcphdr, 5);
   
   tcphdr->chksum = 0;
#if CHECKSUM_GEN_TCP
   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len);
#endif
  TCP_STATS_INC(tcp.xmit);

   /* Send output to IP */
  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);

  pbuf_free(p);

  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", pcb->snd_nxt - 1, pcb->rcv_nxt));
}
Exemplo n.º 17
0
int tls_cmd_get_sta_detail(u32 *sta_num, u8 *buf)
{
#define STA_MAC_BUF_LEN  64
    int len = 0;
    u32 cnt;
    u8 *sta_buf;
    struct ip_addr *ip_addr;
    struct tls_sta_info_t *sta;

    sta_buf = tls_mem_alloc(STA_MAC_BUF_LEN);
    if (NULL == sta_buf)
    {
        return -1;
    }

    memset(sta_buf, 0, STA_MAC_BUF_LEN);
    tls_wifi_get_authed_sta_info(sta_num, sta_buf, STA_MAC_BUF_LEN);
    sta = (struct tls_sta_info_t *)sta_buf;
    for (cnt = 0; cnt < *sta_num; cnt++)
    {
        ip_addr = tls_dhcps_getip(sta->mac_addr);
        if (NULL == ip_addr)
        {
            len += sprintf((char *)(buf+len), ",%02X-%02X-%02X-%02X-%02X-%02X,-",
                                               MAC2STR(sta->mac_addr));
        }
        else
        {
            len += sprintf((char *)(buf+len), ",%02X-%02X-%02X-%02X-%02X-%02X,%d.%d.%d.%d",
                                               MAC2STR(sta->mac_addr),
                                               ip4_addr1(&ip_addr->addr),
                                               ip4_addr2(&ip_addr->addr),
                                               ip4_addr3(&ip_addr->addr),
                                               ip4_addr4(&ip_addr->addr));
        }
        sta++;
    }
    tls_mem_free(sta_buf);

    return 0;
}
Exemplo n.º 18
0
static u8_t ping_recv(void *arg, struct raw_pcb *pcb, 
			struct pbuf *p, ip_addr_t *addr)
{
	struct ip_hdr *iphdr;
	struct icmp_echo_hdr *iecho;
	LWIP_UNUSED_ARG(arg);
	LWIP_UNUSED_ARG(pcb);
	LWIP_UNUSED_ARG(addr);

	LWIP_ASSERT("p != NULL", p != NULL);

	if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr)))) {
		iphdr = (struct ip_hdr *)p->payload;
		iecho = (struct icmp_echo_hdr *)(p->payload + (IPH_HL(iphdr) * 4));
		if ((lns.ping_reply != NULL) &&
		    (iecho->id == PING_ID) && 
		    (iecho->seqno == htons(lns.ping_seq_num))) {
			lns.ping_recv_tstamp = vmm_timer_timestamp();

			lns.ping_reply->ripaddr[0] = ip4_addr1(&lns.ping_addr);
			lns.ping_reply->ripaddr[1] = ip4_addr2(&lns.ping_addr);
			lns.ping_reply->ripaddr[2] = ip4_addr3(&lns.ping_addr);
			lns.ping_reply->ripaddr[3] = ip4_addr4(&lns.ping_addr);
			lns.ping_reply->ttl = IPH_TTL(iphdr);
			lns.ping_reply->len = p->tot_len - (IPH_HL(iphdr) * 4);
			lns.ping_reply->seqno = lns.ping_seq_num;

			vmm_completion_complete(&lns.ping_done);

			/* Free the pbuf */
			pbuf_free(p);

			/* Eat the packet. lwIP should not process it. */
			return 1;
		}
	}

	/* Don't eat the packet. Let lwIP process it. */
	return 0;
}
Exemplo n.º 19
0
void ICACHE_FLASH_ATTR get_wifi2_status(const int8_t cid, const GetWifi2Status *data) {
	gw2sr.header = data->header;
	gw2sr.header.length = sizeof(GetWifi2StatusReturn);

	struct ip_info info;
	wifi_get_ip_info(STATION_IF, &info);
	gw2sr.client_ip[0] = ip4_addr1(&info.ip);
	gw2sr.client_ip[1] = ip4_addr2(&info.ip);
	gw2sr.client_ip[2] = ip4_addr3(&info.ip);
	gw2sr.client_ip[3] = ip4_addr4(&info.ip);
	gw2sr.client_subnet_mask[0] = ip4_addr1(&info.netmask);
	gw2sr.client_subnet_mask[1] = ip4_addr2(&info.netmask);
	gw2sr.client_subnet_mask[2] = ip4_addr3(&info.netmask);
	gw2sr.client_subnet_mask[3] = ip4_addr4(&info.netmask);
	gw2sr.client_gateway[0] = ip4_addr1(&info.gw);
	gw2sr.client_gateway[1] = ip4_addr2(&info.gw);
	gw2sr.client_gateway[2] = ip4_addr3(&info.gw);
	gw2sr.client_gateway[3] = ip4_addr4(&info.gw);

	wifi_get_ip_info(SOFTAP_IF, &info);
	gw2sr.ap_ip[0] = ip4_addr1(&info.ip);
	gw2sr.ap_ip[1] = ip4_addr2(&info.ip);
	gw2sr.ap_ip[2] = ip4_addr3(&info.ip);
	gw2sr.ap_ip[3] = ip4_addr4(&info.ip);
	gw2sr.ap_subnet_mask[0] = ip4_addr1(&info.netmask);
	gw2sr.ap_subnet_mask[1] = ip4_addr2(&info.netmask);
	gw2sr.ap_subnet_mask[2] = ip4_addr3(&info.netmask);
	gw2sr.ap_subnet_mask[3] = ip4_addr4(&info.netmask);
	gw2sr.ap_gateway[0] = ip4_addr1(&info.gw);
	gw2sr.ap_gateway[1] = ip4_addr2(&info.gw);
	gw2sr.ap_gateway[2] = ip4_addr3(&info.gw);
	gw2sr.ap_gateway[3] = ip4_addr4(&info.gw);

	wifi_get_macaddr(STATION_IF, gw2sr.client_mac_address);
	wifi_get_macaddr(SOFTAP_IF, gw2sr.ap_mac_address);

	gw2sr.client_enabled = configuration_current.client_enable;
	gw2sr.ap_enabled = configuration_current.ap_enable;

	gw2sr.client_rssi = wifi_station_get_rssi();

	gw2sr.client_status = wifi_station_get_connect_status();

	gw2sr.ap_connected_count = wifi_softap_get_station_num();

	com_send(&gw2sr, sizeof(GetWifi2StatusReturn), cid);
}
Exemplo n.º 20
0
static int compare_reverse_ptr(struct mdns_state *ms, char *buf)
{
    buf++;
    if (strtol(buf, &buf, 10) != ip4_addr4(&ms->netif->ip_addr))
        return 0;

    buf++;
    if (strtol(buf, &buf, 10) != ip4_addr3(&ms->netif->ip_addr))
        return 0;

    buf++;
    if (strtol(buf, &buf, 10) != ip4_addr2(&ms->netif->ip_addr))
        return 0;

    buf++;
    if (strtol(buf, &buf, 10) != ip4_addr1(&ms->netif->ip_addr))
        return 0;

    if(strcmp(buf, "\x07in-addr\04arpa") == 0)
        return 1;

    return 0;
}
Exemplo n.º 21
0
/**
 * 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] =
Exemplo n.º 22
0
// DNS name resolution callback
static void ICACHE_FLASH_ATTR
tcpClientHostnameCb(const char *name, ip_addr_t *ipaddr, void *arg) {
	struct espconn *conn = arg;
	TcpConn *tci = conn->reverse;
	os_printf("TCP dns CB (%p %p)\n", arg, tci);
	if (ipaddr == NULL) {
		os_printf("TCP %s not found\n", name);
	} else {
		os_printf("TCP %s -> %d.%d.%d.%d\n", name, IP2STR(ipaddr));
		tci->tcp->remote_ip[0] = ip4_addr1(ipaddr);
		tci->tcp->remote_ip[1] = ip4_addr2(ipaddr);
		tci->tcp->remote_ip[2] = ip4_addr3(ipaddr);
		tci->tcp->remote_ip[3] = ip4_addr4(ipaddr);
		os_printf("TCP connect %d.%d.%d.%d (%p)\n", IP2STR(tci->tcp->remote_ip), tci);
		if (espconn_connect(tci->conn) == ESPCONN_OK) {
			tci->state = TCP_conn;
			return;
		}
		os_printf("TCP connect failure\n");
	}
	// oops
	tcpConnFree(tci);
}
Exemplo n.º 23
0
void create_socket_fwup_demo(void)
{
	struct tls_ethif * ethif;
	ethif = tls_netif_get_ethif();
	printf("\nip=%d.%d.%d.%d\n",ip4_addr1(&ethif->ip_addr.addr),ip4_addr2(&ethif->ip_addr.addr),
		ip4_addr3(&ethif->ip_addr.addr),ip4_addr4(&ethif->ip_addr.addr));

	/*oneshot config broadcast mac addr*/
	DemoRawSockOneshotSendMac();
	
	if(fwup_skt_num<0)
	{
		memset(&sock_desc, 0, sizeof(struct tls_socket_desc));
		sock_desc.cs_mode = SOCKET_CS_MODE_SERVER;
		sock_desc.acceptf = socket_fwup_accept;
		sock_desc.recvf = socket_fwup_recv;
		sock_desc.errf = socket_fwup_err;
		sock_desc.pollf = socket_fwup_poll;
		sock_desc.protocol = SOCKET_PROTO_TCP;
		sock_desc.port = SOCKET_FWUP_PORT;
		fwup_skt_num = tls_socket_create(&sock_desc);
	}
}
/**
 * Resolve and fill-in Ethernet address header for outgoing packet.
 *
 * For IP multicast and broadcast, corresponding Ethernet addresses
 * are selected and the packet is transmitted on the link.
 *
 * For unicast addresses, the packet is submitted to etharp_query(). In
 * case the IP address is outside the local network, the IP address of
 * the gateway is used.
 *
 * @param netif The lwIP network interface which the IP packet will be sent on.
 * @param ipaddr The IP address of the packet destination.
 * @param pbuf The pbuf(s) containing the IP packet to be sent.
 *
 * @return
 * - ERR_RTE No route to destination (no gateway to external networks),
 * or the return type of either etharp_query() or netif->linkoutput().
 */
err_t
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
  struct eth_addr *dest, *srcaddr, mcastaddr;
  struct eth_hdr *ethhdr;
  u8_t i;

  /* make room for Ethernet header - should not fail */
  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
    /* bail out */
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
    LINK_STATS_INC(link.lenerr);
    return ERR_BUF;
  }

  /* assume unresolved Ethernet address */
  dest = NULL;
  /* Determine on destination hardware address. Broadcasts and multicasts
   * are special, other IP addresses are looked up in the ARP table. */

  /* broadcast destination IP address? */
  if (ip_addr_isbroadcast(ipaddr, netif)) {
    /* broadcast on Ethernet also */
    dest = (struct eth_addr *)&ethbroadcast;
  /* multicast destination IP address? */
  } else if (ip_addr_ismulticast(ipaddr)) {
    /* Hash IP multicast address to MAC address.*/
    mcastaddr.addr[0] = 0x01;
    mcastaddr.addr[1] = 0x00;
    mcastaddr.addr[2] = 0x5e;
    mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
    mcastaddr.addr[4] = ip4_addr3(ipaddr);
    mcastaddr.addr[5] = ip4_addr4(ipaddr);
    /* destination Ethernet address is multicast */
    dest = &mcastaddr;
  /* unicast destination IP address? */
  } else {
    /* outside local network? */
    if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
      /* interface has default gateway? */
      if (netif->gw.addr != 0) {
        /* send to hardware address of default gateway IP address */
        ipaddr = &(netif->gw);
      /* no default gateway available */
      } else {
        /* no route to destination error (default gateway missing) */
        return ERR_RTE;
      }
    }
    /* queue on destination Ethernet address belonging to ipaddr */
    return etharp_query(netif, ipaddr, q);
  }

  /* continuation for multicast/broadcast destinations */
  /* obtain source Ethernet address of the given interface */
  srcaddr = (struct eth_addr *)netif->hwaddr;
  ethhdr = q->payload;
  for (i = 0; i < netif->hwaddr_len; i++) {
    ethhdr->dest.addr[i] = dest->addr[i];
    ethhdr->src.addr[i] = srcaddr->addr[i];
  }
  ethhdr->type = htons(ETHTYPE_IP);
  /* send packet directly on the link */
  return netif->linkoutput(netif, q);
}
Exemplo n.º 25
0
void ICACHE_FLASH_ATTR packet_counter(espconn *con, uint8_t direction) {
	uint8 ap_ip[4];
	uint8 ap_netmask[4];
	uint8 station_ip[4];
	uint8 station_netmask[4];
	uint8 connection_remote_ip[4];
	struct ip_info info_ap;
	struct ip_info info_station;

	switch(con->type) {
		case ESPCONN_TCP:
			connection_remote_ip[0] = con->proto.tcp->remote_ip[0];
			connection_remote_ip[1] = con->proto.tcp->remote_ip[1];
			connection_remote_ip[2] = con->proto.tcp->remote_ip[2];
			connection_remote_ip[3] = con->proto.tcp->remote_ip[3];
			break;

		case ESPCONN_UDP:
			connection_remote_ip[0] = con->proto.udp->remote_ip[0];
			connection_remote_ip[1] = con->proto.udp->remote_ip[1];
			connection_remote_ip[2] = con->proto.udp->remote_ip[2];
			connection_remote_ip[3] = con->proto.udp->remote_ip[3];
			break;

		default:
			return;
	}

	if(configuration_current.ap_enable) {
		wifi_get_ip_info(SOFTAP_IF, &info_ap);

		ap_ip[0] = ip4_addr1(&info_ap.ip);
		ap_ip[1] = ip4_addr2(&info_ap.ip);
		ap_ip[2] = ip4_addr3(&info_ap.ip);
		ap_ip[3] = ip4_addr4(&info_ap.ip);

		ap_netmask[0] = ip4_addr1(&info_ap.netmask);
		ap_netmask[1] = ip4_addr2(&info_ap.netmask);
		ap_netmask[2] = ip4_addr3(&info_ap.netmask);
		ap_netmask[3] = ip4_addr4(&info_ap.netmask);

		// Determine and match network address.
		if(((connection_remote_ip[0] & ap_netmask[0]) == \
			(ap_ip[0] & ap_netmask[0])) &&
		   ((connection_remote_ip[1] & ap_netmask[1]) == \
			(ap_ip[1] & ap_netmask[1])) &&
		   ((connection_remote_ip[2] & ap_netmask[2]) == \
			(ap_ip[2] & ap_netmask[2])) &&
		   ((connection_remote_ip[3] & ap_netmask[3]) == \
			(ap_ip[3] & ap_netmask[3]))) {
				if(direction == PACKET_COUNT_RX)
					gw2sr.ap_rx_count++;
				else if(direction == PACKET_COUNT_TX)
					gw2sr.ap_tx_count++;
		}
	}

	if(configuration_current.client_enable) {
		wifi_get_ip_info(STATION_IF, &info_station);

		station_ip[0] = ip4_addr1(&info_station.ip);
		station_ip[1] = ip4_addr2(&info_station.ip);
		station_ip[2] = ip4_addr3(&info_station.ip);
		station_ip[3] = ip4_addr4(&info_station.ip);

		station_netmask[0] = ip4_addr1(&info_station.netmask);
		station_netmask[1] = ip4_addr2(&info_station.netmask);
		station_netmask[2] = ip4_addr3(&info_station.netmask);
		station_netmask[3] = ip4_addr4(&info_station.netmask);

		// Determine and match network address.
		if(((connection_remote_ip[0] & station_netmask[0]) == \
			(station_ip[0] & station_netmask[0])) &&
		   ((connection_remote_ip[1] & station_netmask[1]) == \
			(station_ip[1] & station_netmask[1])) &&
		   ((connection_remote_ip[2] & station_netmask[2]) == \
			(station_ip[2] & station_netmask[2])) &&
		   ((connection_remote_ip[3] & station_netmask[3]) == \
			(station_ip[3] & station_netmask[3]))) {
				if(direction == PACKET_COUNT_RX)
					gw2sr.client_rx_count++;
				else if(direction == PACKET_COUNT_TX)
					gw2sr.client_tx_count++;
		}
	}
}
Exemplo n.º 26
0
/**
 * Update (or insert) a IP/MAC address pair in the ARP cache.
 *
 * If a pending entry is resolved, any queued packets will be sent
 * at this point.
 * 
 * @param ipaddr IP address of the inserted ARP entry.
 * @param ethaddr Ethernet address of the inserted ARP entry.
 * @param flags Defines behaviour:
 * - ETHARP_TRY_HARD Allows ARP to insert this as a new item. If not specified,
 * only existing ARP entries will be updated.
 *
 * @return
 * - ERR_OK Succesfully updated ARP cache.
 * - ERR_MEM If we could not add a new ARP entry when ETHARP_TRY_HARD was set.
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 * @see pbuf_free()
 */
err_t
update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u32_t flags)
{
  s8_t i, k;
  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
  LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %lu.%lu.%lu.%lu - %02x:%02x:%02x:%02x:%02x:%02x\n",
                                        ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), 
                                        ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
                                        ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
  /* non-unicast address? */
	/* XXX XXX XXX broadcast control on netif!*/
	if (ip_addr_isany(ipaddr) ||
      /*ip_addr_is_v4broadcast(ipaddr, &(al->ipaddr), &(al->netmask)) ||*/
      ip_addr_ismulticast(ipaddr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
    return ERR_ARG;
  }
  /* find or create ARP entry */
  i = find_entry(ipaddr, flags);
  /* bail out if no entry could be found */
  if (i < 0) return (err_t)i;
  
  /* mark it stable */
  arp_table[i].state = (flags & ATF_PERM)?ETHARP_STATE_PERMANENT:ETHARP_STATE_STABLE;

  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating %s entry %u\n", 
				(flags & ATF_PERM)?"permanent":"stable",i));
	//printf("%lx %lx %lx %lx\n",ipaddr->addr[0],ipaddr->addr[1],ipaddr->addr[2],ipaddr->addr[3]);
  /* update address */
  for (k = 0; k < netif->hwaddr_len; ++k) {
    arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
  }
	arp_table[i].if_id=netif->id;
  /* reset time stamp */
  arp_table[i].ctime = 0;
/* this is where we will send out queued packets! */
#if ARP_QUEUEING
  while (arp_table[i].p != NULL) {
    /* get the first packet on the queue */
    struct pbuf *p = arp_table[i].p;
    /* Ethernet header */
    struct eth_hdr *ethhdr = p->payload;
    /* remember (and reference) remainder of queue */
    /* note: this will also terminate the p pbuf chain */
    arp_table[i].p = pbuf_dequeue(p);
    /* fill-in Ethernet header */
    for (k = 0; k < netif->hwaddr_len; ++k) {
      ethhdr->dest.addr[k] = ethaddr->addr[k];
      ethhdr->src.addr[k] = netif->hwaddr[k];
    }
    // Fix by Renzo Davoli
    //    ethhdr->type = htons(ETHTYPE_IP); 
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n", (void *)p));
    /* send the queued IP packet */
    LINKOUTPUT(netif, p);
    /* free the queued IP packet */
    pbuf_free(p);
  }
#endif
  return ERR_OK;
}
Exemplo n.º 27
0
/**
 * Resolve and fill-in Ethernet address header for outgoing packet.
 *
 * For IP multicast and broadcast, corresponding Ethernet addresses
 * are selected and the packet is transmitted on the link.
 *
 * For unicast addresses, the packet is submitted to etharp_query(). In
 * case the IP address is outside the local network, the IP address of
 * the gateway is used.
 *
 * @param netif The lwIP network interface which the IP packet will be sent on.
 * @param ipaddr The IP address of the packet destination.
 * @param pbuf The pbuf(s) containing the IP packet to be sent.
 *
 * @return
 * - ERR_RTE No route to destination (no gateway to external networks),
 * or the return type of either etharp_query() or netif->linkoutput().
 */
err_t
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
	struct eth_addr *dest, *srcaddr, mcastaddr;
	struct ip_addr_list *al;
	struct eth_hdr *ethhdr;
	u8_t i;
	
	/* make room for Ethernet header - should not fail */
	if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
		/* bail out */
		LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
		LINK_STATS_INC(link.lenerr);
		printf("etharp_output ERR\n");
		return ERR_BUF;
	}

	/* assume unresolved Ethernet address */
	dest = NULL;
	/* Determine on destination hardware address. Broadcasts and multicasts
	 * are special, other IP addresses are looked up in the ARP table. */

	/* broadcast destination IP address? */
	if (ip_addr_is_v4comp(ipaddr)) {

		/* destination IP address is an IP multicast address? */
		if (ip_addr_is_v4multicast(ipaddr)) {

			/* Hash IP multicast address to MAC address. */
			mcastaddr.addr[0] = 0x01;
			mcastaddr.addr[1] = 0x00;
			mcastaddr.addr[2] = 0x5e;
			mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
			mcastaddr.addr[4] = ip4_addr3(ipaddr);
			mcastaddr.addr[5] = ip4_addr4(ipaddr);
			/* destination Ethernet address is multicast */
			dest = &mcastaddr;
			/* unicast destination IP address? */
		} 
		/// CHANGED BY DIEGO BILLI
		else if (ip_addr_is_v4broadcast_allones(ipaddr)) {
			dest = (struct eth_addr *)&ethbroadcast;
		}
		else {

			/* destination IP network address not on local network?
			*        * IP layer wants us to forward to the default gateway */
			if ((al=ip_addr_list_maskfind(netif->addrs, ipaddr)) == NULL) {
				return -1;
			}
			/* destination IP address is an IP broadcast address? */
			if (ip_addr_isany(ipaddr) || ip_addr_is_v4broadcast(ipaddr, &(al->ipaddr), &(al->netmask))) {
				/* broadcast on Ethernet also */
				dest = (struct eth_addr *)&ethbroadcast;
			}
		}
	}
	else {
		if (ip_addr_isany(ipaddr) || ip_addr_ismulticast(ipaddr)) {
			mcastaddr.addr[0] = 0x33;
			mcastaddr.addr[1] = 0x33;
			mcastaddr.addr[2] = 0xff;
			mcastaddr.addr[3] = ipaddr->addr[3] >> 16 & 0xff;
			mcastaddr.addr[4] = ipaddr->addr[3] >> 8 & 0xff;
			mcastaddr.addr[5] = ipaddr->addr[3] & 0xff;
			dest = &mcastaddr;
		}
		/* destination IP network address not on local network?
		* IP layer wants us to forward to the default gateway */
		/* XXX what is this? Is it incomplete code? */
		else if ((al=ip_addr_list_maskfind(netif->addrs, ipaddr)) == NULL) {
Exemplo n.º 28
0
/**
 * This function is called by the network interface device driver when
 * an IP packet is received. The function does the basic checks of the
 * IP header such as packet size being at least larger than the header
 * size etc. If the packet was not destined for us, the packet is
 * forwarded (using ip_forward). The IP checksum is always checked.
 *
 * Finally, the packet is sent to the upper layer protocol input function.
 * 
 * @param p the received IP packet (p->payload points to IP header)
 * @param inp the netif on which this packet was received
 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
 *         processed, but currently always returns ERR_OK)
 */
err_t
ip_input(struct pbuf *p, struct netif *inp)
{
  struct ip_hdr *iphdr;
  struct netif *netif;
  u16_t iphdr_hlen;
  u16_t iphdr_len;
#if LWIP_DHCP
  int check_ip_src=1;
#endif /* LWIP_DHCP */

  IP_STATS_INC(ip.recv);
  snmp_inc_ipinreceives();

  /* identify the IP header */
  iphdr = p->payload;
  if (IPH_V(iphdr) != 4) {
    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
    ip_debug_print(p);
    pbuf_free(p);
    IP_STATS_INC(ip.err);
    IP_STATS_INC(ip.drop);
    snmp_inc_ipinhdrerrors();
    return ERR_OK;
  }

  /* obtain IP header length in number of 32-bit words */
  iphdr_hlen = IPH_HL(iphdr);
  /* calculate IP header length in bytes */
  iphdr_hlen *= 4;
  /* obtain ip length in bytes */
  iphdr_len = ntohs(IPH_LEN(iphdr));

  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
  if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
    if (iphdr_hlen > p->len) {
      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
        ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
        iphdr_hlen, p->len));
    }
    if (iphdr_len > p->tot_len) {
      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
        ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
        iphdr_len, p->tot_len));
    }
    /* free (drop) packet pbufs */
    pbuf_free(p);
    IP_STATS_INC(ip.lenerr);
    IP_STATS_INC(ip.drop);
    snmp_inc_ipindiscards();
    return ERR_OK;
  }

  /* verify checksum */
#if CHECKSUM_CHECK_IP
  if (inet_chksum(iphdr, iphdr_hlen) != 0) {

    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
      ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
    ip_debug_print(p);
    pbuf_free(p);
    IP_STATS_INC(ip.chkerr);
    IP_STATS_INC(ip.drop);
    snmp_inc_ipinhdrerrors();
    return ERR_OK;
  }
#endif

  /* Trim pbuf. This should have been done at the netif layer,
   * but we'll do it anyway just to be sure that its done. */
  pbuf_realloc(p, iphdr_len);

  /* match packet against an interface, i.e. is this packet for us? */
#if LWIP_IGMP
  if (ip_addr_ismulticast(&(iphdr->dest))) {
    if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &(iphdr->dest)))) {
      netif = inp;
    } else {
      netif = NULL;
    }
  } else
#endif /* LWIP_IGMP */
  {
    /* start trying with inp. if that's not acceptable, start walking the
       list of configured netifs.
       'first' is used as a boolean to mark whether we started walking the list */
    int first = 1;
    netif = inp;
    do {
      LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
          iphdr->dest.addr, netif->ip_addr.addr,
          iphdr->dest.addr & netif->netmask.addr,
          netif->ip_addr.addr & netif->netmask.addr,
          iphdr->dest.addr & ~(netif->netmask.addr)));

      /* interface is up and configured? */
      if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
        /* unicast to this interface address? */
        if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
            /* or broadcast on this interface network address? */
            ip_addr_isbroadcast(&(iphdr->dest), netif)) {
          LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
              netif->name[0], netif->name[1]));
          /* break out of for loop */
          break;
        }
      }
      if (first) {
        first = 0;
        netif = netif_list;
      } else {
        netif = netif->next;
      }
      if (netif == inp) {
        netif = netif->next;
      }
    } while(netif != NULL);
  }

#if LWIP_DHCP
  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
   * According to RFC 1542 section 3.1.1, referred by RFC 2131).
   */
  if (netif == NULL) {
    /* remote port is DHCP server? */
    if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
        ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest)));
      if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest) == DHCP_CLIENT_PORT) {
        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n"));
        netif = inp;
        check_ip_src = 0;
      }
    }
  }
#endif /* LWIP_DHCP */

  /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
#if LWIP_DHCP
  /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
  if (check_ip_src && (iphdr->src.addr != 0))
#endif /* LWIP_DHCP */
  {  if ((ip_addr_isbroadcast(&(iphdr->src), inp)) ||
         (ip_addr_ismulticast(&(iphdr->src)))) {
      /* packet source is not valid */
      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
      /* free (drop) packet pbufs */
      pbuf_free(p);
      IP_STATS_INC(ip.drop);
      snmp_inc_ipinaddrerrors();
      snmp_inc_ipindiscards();
      return ERR_OK;
    }
  }

  /* packet not for us? */
  if (netif == NULL) {
    /* packet not for us, route or discard */
    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
#if IP_FORWARD
    /* non-broadcast packet? */
    if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
      /* try to forward IP packet on (other) interfaces */
      ip_forward(p, iphdr, inp);
    } else
#endif /* IP_FORWARD */
    {
      snmp_inc_ipinaddrerrors();
      snmp_inc_ipindiscards();
    }
    pbuf_free(p);
    return ERR_OK;
  }
  /* packet consists of multiple fragments? */
  if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
#if IP_REASSEMBLY /* packet fragment reassembly code present? */
    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",
      ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
    /* reassemble the packet*/
    p = ip_reass(p);
    /* packet not fully reassembled yet? */
    if (p == NULL) {
      return ERR_OK;
    }
    iphdr = p->payload;
#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
    pbuf_free(p);
    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
      ntohs(IPH_OFFSET(iphdr))));
    IP_STATS_INC(ip.opterr);
    IP_STATS_INC(ip.drop);
    /* unsupported protocol feature */
    snmp_inc_ipinunknownprotos();
    return ERR_OK;
#endif /* IP_REASSEMBLY */
  }

#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */

#if LWIP_IGMP
  /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
  if((iphdr_hlen > IP_HLEN &&  (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
#else
  if (iphdr_hlen > IP_HLEN) {
#endif /* LWIP_IGMP */
    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
    pbuf_free(p);
    IP_STATS_INC(ip.opterr);
    IP_STATS_INC(ip.drop);
    /* unsupported protocol feature */
    snmp_inc_ipinunknownprotos();
    return ERR_OK;
  }
#endif /* IP_OPTIONS_ALLOWED == 0 */

  /* send to upper layers */
  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
  ip_debug_print(p);
  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));

  current_netif = inp;
  current_header = iphdr;

#if LWIP_RAW
  /* raw input did not eat the packet? */
  if (raw_input(p, inp) == 0)
#endif /* LWIP_RAW */
  {

    switch (IPH_PROTO(iphdr)) {
#if LWIP_UDP
    case IP_PROTO_UDP:
#if LWIP_UDPLITE
    case IP_PROTO_UDPLITE:
#endif /* LWIP_UDPLITE */
      snmp_inc_ipindelivers();
      udp_input(p, inp);
      break;
#endif /* LWIP_UDP */
#if LWIP_TCP
    case IP_PROTO_TCP:
      snmp_inc_ipindelivers();
      tcp_input(p, inp);
      break;
#endif /* LWIP_TCP */
#if LWIP_ICMP
    case IP_PROTO_ICMP:
      snmp_inc_ipindelivers();
      icmp_input(p, inp);
      break;
#endif /* LWIP_ICMP */
#if LWIP_IGMP
    case IP_PROTO_IGMP:
      igmp_input(p,inp,&(iphdr->dest));
      break;
#endif /* LWIP_IGMP */
    default:
#if LWIP_ICMP
      /* send ICMP destination protocol unreachable unless is was a broadcast */
      if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
          !ip_addr_ismulticast(&(iphdr->dest))) {
        p->payload = iphdr;
        icmp_dest_unreach(p, ICMP_DUR_PROTO);
      }
#endif /* LWIP_ICMP */
      pbuf_free(p);

      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));

      IP_STATS_INC(ip.proterr);
      IP_STATS_INC(ip.drop);
      snmp_inc_ipinunknownprotos();
    }
  }

  current_netif = NULL;
  current_header = NULL;

  return ERR_OK;
}

/**
 * Sends an IP packet on a network interface. This function constructs
 * the IP header and calculates the IP header checksum. If the source
 * IP address is NULL, the IP address of the outgoing network
 * interface is filled in as source address.
 * 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)
{
#if IP_OPTIONS_SEND
  return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
}

/**
 * Same as ip_output_if() but with the possibility to include IP options:
 *
 * @ param ip_options pointer to the IP options, copied into the IP header
 * @ param optlen length of ip_options
 */
err_t ip_output_if_opt(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
       u16_t optlen)
{
#endif /* IP_OPTIONS_SEND */
  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) {
    u16_t ip_hlen = IP_HLEN;
#if IP_OPTIONS_SEND
    u16_t optlen_aligned = 0;
    if (optlen != 0) {
      /* round up to a multiple of 4 */
      optlen_aligned = ((optlen + 3) & ~3);
      ip_hlen += optlen_aligned;
      /* First write in the IP options */
      if (pbuf_header(p, optlen_aligned)) {
        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
        IP_STATS_INC(ip.err);
        snmp_inc_ipoutdiscards();
        return ERR_BUF;
      }
      MEMCPY(p->payload, ip_options, optlen);
      if (optlen < optlen_aligned) {
        /* zero the remaining bytes */
        memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
      }
    }
#endif /* IP_OPTIONS_SEND */
    /* generate IP header */
    if (pbuf_header(p, IP_HLEN)) {
      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("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
  } else {
    /* IP header already included in p */
    iphdr = p->payload;
    dest = &(iphdr->dest);
  }

  IP_STATS_INC(ip.xmit);

  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
  ip_debug_print(p);

#if ENABLE_LOOPBACK
  if (ip_addr_cmp(dest, &netif->ip_addr)) {
    /* Packet to self, enqueue it for loopback */
    LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
    return netif_loop_output(netif, p, dest);
  }
#endif /* ENABLE_LOOPBACK */
#if IP_FRAG
  /* don't fragment if interface has mtu set to 0 [loopif] */
  if (netif->mtu && (p->tot_len > netif->mtu)) {
    return ip_frag(p,netif,dest);
  }
#endif

  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
  return netif->output(netif, p, dest);
}

/**
 * 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
 */
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, ("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, tos, proto, netif);
}

#if LWIP_NETIF_HWADDRHINT
/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
 *  before calling ip_output_if.
 *
 * @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 addr_hint address hint pointer set to netif->addr_hint before
 *        calling ip_output_if()
 *
 * @return ERR_RTE if no route is found
 *         see ip_output_if() for more return values
 */
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;
}
#endif /* LWIP_NETIF_HWADDRHINT*/

#if IP_DEBUG
/* Print an IP header by using LWIP_DEBUGF
 * @param p an IP packet, p->payload pointing to the IP header
 */
void
ip_debug_print(struct pbuf *p)
{
  struct ip_hdr *iphdr = p->payload;
  u8_t *payload;

  payload = (u8_t *)iphdr + IP_HLEN;

  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",
                    IPH_V(iphdr),
                    IPH_HL(iphdr),
                    IPH_TOS(iphdr),
                    ntohs(IPH_LEN(iphdr))));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",
                    ntohs(IPH_ID(iphdr)),
                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",
                    IPH_TTL(iphdr),
                    IPH_PROTO(iphdr),
                    ntohs(IPH_CHKSUM(iphdr))));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",
                    ip4_addr1(&iphdr->src),
                    ip4_addr2(&iphdr->src),
                    ip4_addr3(&iphdr->src),
                    ip4_addr4(&iphdr->src)));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",
                    ip4_addr1(&iphdr->dest),
                    ip4_addr2(&iphdr->dest),
                    ip4_addr3(&iphdr->dest),
                    ip4_addr4(&iphdr->dest)));
  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
}
Exemplo n.º 29
0
/**
 * Update (or insert) a IP/MAC address pair in the ARP cache.
 *
 * If a pending entry is resolved, any queued packets will be sent
 * at this point.
 * 
 * @param ipaddr IP address of the inserted ARP entry.
 * @param ethaddr Ethernet address of the inserted ARP entry.
 * @param flags Defines behaviour:
 * - ETHARP_TRY_HARD Allows ARP to insert this as a new item. If not specified,
 * only existing ARP entries will be updated.
 *
 * @return
 * - ERR_OK Succesfully updated ARP cache.
 * - ERR_MEM If we could not add a new ARP entry when ETHARP_TRY_HARD was set.
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 * @see pbuf_free()
 */
static err_t
update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
{
  s8_t i;
  u8_t k;
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 3, ("update_arp_entry()\n"));
  LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_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(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), 
                                        ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
                                        ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
  /* non-unicast address? */
  if (ip_addr_isany(ipaddr) ||
      ip_addr_isbroadcast(ipaddr, netif) ||
      ip_addr_ismulticast(ipaddr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
    return ERR_ARG;
  }
  /* find or create ARP entry */
#if LWIP_NETIF_HWADDRHINT
  i = find_entry(ipaddr, flags, netif);
#else /* LWIP_NETIF_HWADDRHINT */
  i = find_entry(ipaddr, flags);
#endif /* LWIP_NETIF_HWADDRHINT */
  /* bail out if no entry could be found */
  if (i < 0)
    return (err_t)i;
  
  /* mark it stable */
  arp_table[i].state = ETHARP_STATE_STABLE;
  /* record network interface */
  arp_table[i].netif = netif;

  /* insert in SNMP ARP index tree */
  snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);

  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
  /* update address */
  k = ETHARP_HWADDR_LEN;
  while (k > 0) {
    k--;
    arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
  }
  /* reset time stamp */
  arp_table[i].ctime = 0;
#if ARP_QUEUEING
  /* this is where we will send out queued packets! */
  while (arp_table[i].q != NULL) {
    struct pbuf *p;
    /* remember remainder of queue */
    struct etharp_q_entry *q = arp_table[i].q;
    /* pop first item off the queue */
    arp_table[i].q = q->next;
    /* get the packet pointer */
    p = q->p;
    /* now queue entry can be freed */
    memp_free(MEMP_ARP_QUEUE, q);
    /* send the queued IP packet */
    etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
    /* free the queued IP packet */
    pbuf_free(p);
  }
#endif
  return ERR_OK;
}
Exemplo n.º 30
0
/**
 * 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;
}