Esempio n. 1
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)));
}
Esempio n. 2
0
/**
 * Bind the interface to the offered IP address.
 *
 */
static void dhcp_bind(struct dhcp_state *state)
{
  struct ip_addr sn_mask, gw_addr;
  dhcp_set_state(state, DHCP_BOUND);

  if (state->offered_t1_renew != 0xffffffffUL)
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_bind(): t1 renewal timer %u secs\n", state->offered_t1_renew));
    state->t1_timeout = (state->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
    if (state->t1_timeout == 0) state->t1_timeout = 1;
    DEBUGF(DHCP_DEBUG, ("dhcp_bind(): request timeout %u msecs\n", state->offered_t1_renew*1000));
  }
  if (state->offered_t2_rebind != 0xffffffffUL)
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_bind(): t2 rebind timer %u secs\n", state->offered_t2_rebind));
    state->t2_timeout = (state->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
    if (state->t2_timeout == 0) state->t2_timeout = 1;
    DEBUGF(DHCP_DEBUG, ("dhcp_bind(): request timeout %u msecs\n", state->offered_t2_rebind*1000));
  }

  ip_addr_set(&sn_mask, &state->offered_sn_mask);
  // subnet mask not given
  if (sn_mask.addr == 0)
  {
    // choose a safe subnet mask given the network class
    u8_t first_octet = ip4_addr1(&sn_mask);
    if (first_octet <= 127) sn_mask.addr = htonl(0xff000000);
    else if (first_octet >= 192) sn_mask.addr = htonl(0xffffff00);
    else sn_mask.addr = htonl(0xffff0000);
  }
  DEBUGF(DHCP_DEBUG, ("dhcp_bind(): SN: 0x%08x\n", sn_mask.addr));
  netif_set_netmask(state->netif, &sn_mask);

  ip_addr_set(&gw_addr, &state->offered_gw_addr);
  // gateway address not given
  if (gw_addr.addr == 0)
  {
    gw_addr.addr &= sn_mask.addr;
    gw_addr.addr |= 0x01000000;
  }
  DEBUGF(DHCP_DEBUG, ("dhcp_bind(): GW: 0x%08x\n", gw_addr.addr));
  netif_set_gw(state->netif, &gw_addr);

  DEBUGF(DHCP_DEBUG, ("dhcp_bind(): IP: 0x%08x\n", state->offered_ip_addr.addr));
  netif_set_ipaddr(state->netif, &state->offered_ip_addr);

  l4e_printf("dhcp: %hd.%hd.%hd.%hd/%hd.%hd.%hd.%hd, gw %hd.%hd.%hd.%hd\n",
      ip_split(&state->offered_ip_addr), ip_split(&sn_mask),
      ip_split(&gw_addr));
}
Esempio n. 3
0
File: ip6.c Progetto: 0xBADCA7/lk
err_t
ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
       u8_t ttl,
       u8_t proto, struct netif *netif)
{
  struct ip_hdr *iphdr;

  PERF_START;

  LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len));
  if (pbuf_header(p, IP_HLEN)) {
    LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
    IP_STATS_INC(ip.err);

    return ERR_BUF;
  }
  LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len));

  iphdr = p->payload;


  if (dest != IP_HDRINCL) {
    LWIP_DEBUGF(IP_DEBUG, ("!IP_HDRLINCL\n"));
    iphdr->hoplim = ttl;
    iphdr->nexthdr = proto;
    iphdr->len = htons(p->tot_len - IP_HLEN);
    ip_addr_set(&(iphdr->dest), dest);

    iphdr->v = 6;

    if (ip_addr_isany(src)) {
      ip_addr_set(&(iphdr->src), &(netif->ip_addr));
    } else {
      ip_addr_set(&(iphdr->src), src);
    }

  } else {
    dest = &(iphdr->dest);
  }

  IP_STATS_INC(ip.xmit);

  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len));
#if IP_DEBUG
  ip_debug_print(p);
#endif /* IP_DEBUG */

  PERF_STOP("ip_output_if");
  return netif->output(netif, p, dest);
}
Esempio n. 4
0
/**
 * Abandons a connection and optionally sends a RST to the remote
 * host.  Deletes the local protocol control block. This is done when
 * a connection is killed because of shortage of memory.
 *
 * @param pcb the tcp_pcb to abort
 * @param reset boolean to indicate whether a reset should be sent
 */
void
tcp_abandon(struct tcp_pcb *pcb, int reset)
{
  u32_t seqno, ackno;
  u16_t remote_port, local_port;
  struct ip_addr remote_ip, local_ip;
#if LWIP_CALLBACK_API  
  void (* errf)(void *arg, err_t err);
#endif /* LWIP_CALLBACK_API */
  void *errf_arg;

  
  /* Figure out on which TCP PCB list we are, and remove us. If we
     are in an active state, call the receive function associated with
     the PCB with a NULL argument, and send an RST to the remote end. */
  if (pcb->state == TIME_WAIT) {
    tcp_pcb_remove(&tcp_tw_pcbs, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
  } else {
    seqno = pcb->snd_nxt;
    ackno = pcb->rcv_nxt;
    ip_addr_set(&local_ip, &(pcb->local_ip));
    ip_addr_set(&remote_ip, &(pcb->remote_ip));
    local_port = pcb->local_port;
    remote_port = pcb->remote_port;
#if LWIP_CALLBACK_API
    errf = pcb->errf;
#endif /* LWIP_CALLBACK_API */
    errf_arg = pcb->callback_arg;
    tcp_pcb_remove(&tcp_active_pcbs, pcb);
    if (pcb->unacked != NULL) {
      tcp_segs_free(pcb->unacked);
    }
    if (pcb->unsent != NULL) {
      tcp_segs_free(pcb->unsent);
    }
#if TCP_QUEUE_OOSEQ    
    if (pcb->ooseq != NULL) {
      tcp_segs_free(pcb->ooseq);
    }
#endif /* TCP_QUEUE_OOSEQ */
    memp_free(MEMP_TCP_PCB, pcb);
    TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
    if (reset) {
      LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
      tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
    }
  }
}
Esempio n. 5
0
/*-----------------------------------------------------------------------------------*/
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;

}
Esempio n. 6
0
struct tcp_pcb *
tcp_listen(struct tcp_pcb *pcb)
{
  struct tcp_pcb_listen *lpcb;

  /* already listening? */
  if (pcb->state == LISTEN) {
    return pcb;
  }
  lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);
  if (lpcb == NULL) {
    return NULL;
  }
  lpcb->callback_arg = pcb->callback_arg;
  lpcb->local_port = pcb->local_port;
  lpcb->state = LISTEN;
  lpcb->so_options = pcb->so_options;
  lpcb->so_options |= SOF_ACCEPTCONN;
  lpcb->ttl = pcb->ttl;
  lpcb->tos = pcb->tos;
  ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
  memp_free(MEMP_TCP_PCB, pcb);
#if LWIP_CALLBACK_API
  lpcb->accept = tcp_accept_null;
#endif /* LWIP_CALLBACK_API */
  TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
  return (struct tcp_pcb *)lpcb;
}
int
lwip_gethostbyname_r0(const char *name, ip_addr_t *addr, int *h_errnop)
{
	ip_addr_t laddr;
	err_t err;
	int lh_errno;

	if (h_errnop == NULL) {
		/* ensure h_errnop is never NULL */
		h_errnop = &lh_errno;
	}

	/* first thing to do: set *result to nothing */
	if ( name == NULL ) {
		/* not all arguments given */
		*h_errnop = EINVAL;
		return -1;
	}

	/* query host IP address */
	err = netconn_gethostbyname(name, &laddr);
	if (err != ERR_OK) {
		LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname_r0(%s) failed, err=%d\n", name, err));
		*h_errnop = ENSRNOTFOUND;
		return -1;
	}
	ip_addr_set(addr,&laddr);
	return 0;
}
Esempio n. 8
0
/**
 * Sets IPv4 address for this trap destination.
 * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
 * @param dst IPv4 address in host order.
 */
void
snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst)
{
  if (dst_idx < SNMP_TRAP_DESTINATIONS) {
    ip_addr_set(&trap_dst[dst_idx].dip, dst);
  }
}
Esempio n. 9
0
/**
 * Search for a specific igmp group and create a new one if not found-
 *
 * @param ifp the network interface for which to look
 * @param addr the group ip address to search
 * @return a struct igmp_group*,
 *         NULL on memory error.
 */
struct igmp_group *
igmp_lookup_group(struct netif *ifp, ip_addr_t *addr)
{
  struct igmp_group *group = igmp_group_list;

  /* Search if the group already exists */
  group = igmp_lookfor_group(ifp, addr);
  if (group != NULL) {
    /* Group already exists. */
    return group;
  }

  /* Group doesn't exist yet, create a new one */
  group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
  if (group != NULL) {
    group->netif              = ifp;
    ip_addr_set(&(group->group_address), addr);
    group->timer              = 0; /* Not running */
    group->group_state        = IGMP_GROUP_NON_MEMBER;
    group->last_reporter_flag = 0;
    group->use                = 0;
    group->next               = igmp_group_list;

    igmp_group_list = group;
  }

  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to ")));
  ip_addr_debug_print(IGMP_DEBUG, addr);
  LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", ifp));

  return group;
}
Esempio n. 10
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, ip_addr_t *gw)
{
	ip_addr_set(&(netif->gw), gw);
	LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
		    ("netif: GW address of interface %c%c set to " IP4_F "\n",
		     netif->name[0], netif->name[1], IP4_FV(&netif->gw)));
}
Esempio n. 11
0
/** Actually send an sntp request to a server.
 *
 * @param server_addr resolved IP address of the SNTP server
 */
static void sntp_send_request(ip_addr_t *server_addr) {
    struct pbuf* p;
    p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM);

    if (p != NULL) {
        struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload;
        LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n"));

        /* Initialize request message */
        sntp_initialize_request(sntpmsg);

        /* Send request */
        udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT);
        pbuf_free(p);    // [iva2k] fixing memory leak

        /* Set up receive timeout: try next server or retry on timeout */
        sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);

#if SNTP_CHECK_RESPONSE >= 1
        /* Save server address to verify it in sntp_recv */
        ip_addr_set(&sntp_last_server_address, server_addr);
#endif /* SNTP_CHECK_RESPONSE >= 1 */
    } else {
        LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
                                         (u32_t)SNTP_RETRY_TIMEOUT));
        /* Out of memory: set up a timer to send a retry */
        sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
    }
}
Esempio n. 12
0
File: udp.c Progetto: HarryR/sanos
err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, unsigned short port) {
  struct udp_pcb *ipcb;

  if (!ip_addr_isany(ipaddr) && !ip_ownaddr(ipaddr)) return -EADDRNOTAVAIL;
  ip_addr_set(&pcb->local_ip, ipaddr);

  if (port != 0) {
    pcb->local_port = port;
  } else {
    pcb->local_port = udp_new_port();
  }

  // Insert UDP PCB into the list of active UDP PCBs
  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
    // If it is already on the list, just return
    if (pcb == ipcb) return 0;
  }

  // We need to place the PCB on the list
  pcb->next = udp_pcbs;
  udp_pcbs = pcb;

  //kprintf("udp_bind: bound to port %d\n", port);

  return 0;
}
Esempio n. 13
0
/**
 * 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);
}
Esempio n. 14
0
/**
 * Disconnect a UDP PCB
 *
 * @param pcb the udp pcb to disconnect.
 */
void
udp_disconnect(struct udp_pcb *pcb)
{
  /* reset remote address association */
  ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
  pcb->remote_port = 0;
  /* mark PCB as unconnected */
  pcb->flags &= ~UDP_FLAGS_CONNECTED;
}
Esempio n. 15
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, ip_addr_t *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,
		    ("netif: netmask of interface %c%c set to " IP4_F "\n",
		     netif->name[0], netif->name[1], IP4_FV(&netif->netmask)));
}
Esempio n. 16
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)));
}
Esempio n. 17
0
void
netif_set_gw(struct netif *netif, struct ip_addr *gw)
{
  ip_addr_set(&(netif->gw), gw);
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | 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)));
}
Esempio n. 18
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, ip_addr_t *gw)
{
  ip_addr_set(&(netif->gw), gw);
  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("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_16(&netif->gw),
    ip4_addr2_16(&netif->gw),
    ip4_addr3_16(&netif->gw),
    ip4_addr4_16(&netif->gw)));
}
Esempio n. 19
0
int ethApplyIPConfig(void) {
	t_ip_info ip_info;
	struct ip_addr ipaddr, netmask, gw, dns, dns_curr;
	int result;

	if((result = ps2ip_getconfig("sm0", &ip_info)) >= 0) {
		IP4_ADDR(&ipaddr, ps2_ip[0], ps2_ip[1], ps2_ip[2], ps2_ip[3]);
		IP4_ADDR(&netmask, ps2_netmask[0], ps2_netmask[1], ps2_netmask[2], ps2_netmask[3]);
		IP4_ADDR(&gw, ps2_gateway[0], ps2_gateway[1], ps2_gateway[2], ps2_gateway[3]);
		IP4_ADDR(&dns, ps2_dns[0], ps2_dns[1], ps2_dns[2], ps2_dns[3]);
		dns_curr = dns_getserver(0);

		//Check if it's the same. Otherwise, apply the new configuration.
		if((ps2_ip_use_dhcp != ip_info.dhcp_enabled) || (!ps2_ip_use_dhcp &&
			(!ip_addr_cmp(&ipaddr, (struct ip_addr*)&ip_info.ipaddr)	||
			!ip_addr_cmp(&netmask, (struct ip_addr*)&ip_info.netmask)	||
			!ip_addr_cmp(&gw, (struct ip_addr*)&ip_info.gw)			||
			!ip_addr_cmp(&dns, &dns_curr)))) {
				if(ps2_ip_use_dhcp){
					IP4_ADDR((struct ip_addr*)&ip_info.ipaddr, 169, 254, 0, 1);
					IP4_ADDR((struct ip_addr*)&ip_info.netmask, 255, 255, 0, 0);
					IP4_ADDR((struct ip_addr*)&ip_info.gw, 0, 0, 0, 0);
					IP4_ADDR(&dns, 0, 0, 0, 0);

					ip_info.dhcp_enabled = 1;
				}else{
					ip_addr_set((struct ip_addr*)&ip_info.ipaddr, &ipaddr);
					ip_addr_set((struct ip_addr*)&ip_info.netmask, &netmask);
					ip_addr_set((struct ip_addr*)&ip_info.gw, &gw);

					ip_info.dhcp_enabled = 0;
				}

				dns_setserver(0, &dns);
				result = ps2ip_setconfig(&ip_info);
		}else result = 0;
	}

	return result;
}
Esempio n. 20
0
/**
 * 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;
}
Esempio n. 21
0
s8_t uip_ipoutput_if(struct uip_pbuf *p,struct uip_ip_addr *src,struct uip_ip_addr *dst,u8_t ttl,u8_t tos,u8_t proto,struct uip_netif *netif)
{
	struct uip_ip_hdr *iphdr = NULL;
	u16_t ip_id = 0;

	if(dst!=NULL) {
		if(uip_pbuf_header(p,UIP_IP_HLEN)) {
			UIP_ERROR("uip_ipoutput_if: not enough room for IP header in pbuf.\n");
			return UIP_ERR_BUF;
		}

		iphdr = p->payload;

		UIP_IPH_TTL_SET(iphdr,ttl);
		UIP_IPH_PROTO_SET(iphdr,proto);

		ip_addr_set(&iphdr->dst,dst);

		UIP_IPH_VHLTOS_SET(iphdr,4,(UIP_IP_HLEN/4),tos);
		UIP_IPH_LEN_SET(iphdr,htons(p->tot_len));
		UIP_IPH_OFFSET_SET(iphdr,htons(UIP_IP_DF));
		UIP_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);

		UIP_IPH_CHKSUM_SET(iphdr,0);
		UIP_IPH_CHKSUM_SET(iphdr,uip_ipchksum(iphdr,UIP_IP_HLEN));
	} else {
		iphdr = p->payload;
		dst = &iphdr->dst;
	}
#if UIP_IP_FRAG
	if(netif->mtu && p->tot_len>netif->mtu)
		return uip_ipfrag(p,netif,dst);
#endif
	return netif->output(netif,p,dst);
}
Esempio n. 22
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)));
}
Esempio n. 23
0
/*-----------------------------------------------------------------------------------*/
void
tcp_abort(struct tcp_pcb *pcb)
{
  u32_t seqno, ackno;
  u16_t remote_port, local_port;
  struct ip_addr remote_ip, local_ip;
  void (* errf)(void *arg, err_t err);
  void *errf_arg;

  
  /* Figure out on which TCP PCB list we are, and remove us. If we
     are in an active state, call the receive function associated with
     the PCB with a NULL argument, and send an RST to the remote end. */
  if(pcb->state == TIME_WAIT) {
    tcp_pcb_remove(TCP_LIST_TW, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
  } else if(pcb->state == LISTEN) {
    tcp_pcb_remove(TCP_LIST_LISTEN, pcb);
    memp_free(MEMP_TCP_PCB_LISTEN, pcb);
  } else {
    seqno = pcb->snd_nxt;
    ackno = pcb->rcv_nxt;
    ip_addr_set(&local_ip, &(pcb->local_ip));
    ip_addr_set(&remote_ip, &(pcb->remote_ip));
    local_port = pcb->local_port;
    remote_port = pcb->remote_port;
    errf = pcb->errf;
    errf_arg = pcb->callback_arg;
    tcp_pcb_remove(TCP_LIST_ACTIVE, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
    if(errf != NULL) {
      errf(errf_arg, ERR_ABRT);
    }
    DEBUGF(TCP_RST_DEBUG, ("tcp_abort: sending RST\n"));
    tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
  }
}
Esempio n. 24
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, ip_addr_t *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, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
	((netif->name[0]) ?netif->name[0] :'-'),
	((netif->name[1]) ?netif->name[1] :'-'),
    ip4_addr1_16(&netif->netmask),
    ip4_addr2_16(&netif->netmask),
    ip4_addr3_16(&netif->netmask),
    ip4_addr4_16(&netif->netmask)));
}
Esempio n. 25
0
/**
 * Start the DHCP process, discover a server
 *
 */
static err_t dhcp_discover(struct dhcp_state *state)
{
  err_t result = ERR_OK;
  u16_t msecs;
  DEBUGF(DHCP_DEBUG, ("dhcp_discover(%p)\n", state));
  ip_addr_set(&state->offered_ip_addr, IP_ADDR_ANY);
  // create and initialize the DHCP message header
  DEBUGF(DHCP_DEBUG, ("set ip addr, creating request()\n"));

  result = dhcp_create_request(state);
  DEBUGF(DHCP_DEBUG, ("created request\n"));
  
  if (result == ERR_OK)
  {
    dhcp_option(state, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
    dhcp_option_byte(state, DHCP_DISCOVER);

    dhcp_option(state, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
    dhcp_option_short(state, 576);

    dhcp_option(state, DHCP_OPTION_PARAMETER_REQUEST_LIST, 3);
    dhcp_option_byte(state, DHCP_OPTION_SUBNET_MASK);
    dhcp_option_byte(state, DHCP_OPTION_ROUTER);
    dhcp_option_byte(state, DHCP_OPTION_BROADCAST);

    dhcp_option_trailer(state);

    pbuf_realloc(state->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + state->options_out_len);
    DEBUGF(DHCP_DEBUG, ("about to do udp recv\n"));
    udp_recv(state->pcb, dhcp_recv, state);
    DEBUGF(DHCP_DEBUG, ("about to do udp bind\n"));
    udp_bind(state->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
    DEBUGF(DHCP_DEBUG, ("about to do udp connect\n"));
    udp_connect(state->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);

    DEBUGF(DHCP_DEBUG, ("about to do udp send\n"));
    udp_send(state->pcb, state->p_out);
    udp_bind(state->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
    udp_connect(state->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
    dhcp_delete_request(state);
  }
  state->tries++;
  msecs = state->tries < 4 ? (state->tries + 1) * 1000 : 10 * 1000;
  state->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
  DEBUGF(DHCP_DEBUG, ("dhcp_discover(): request timeout %u msecs\n", msecs));
  dhcp_set_state(state, DHCP_SELECTING);
  return result;
}
Esempio n. 26
0
/**
 * Extract options from the server ACK message.
 *
 */
static void dhcp_handle_ack(struct dhcp_state *state)
{
  u8_t *option_ptr;
//  state->offered_t0_lease;
//  state->offered_t1_renew;
//  state->offered_t2_rebind;
  state->offered_sn_mask.addr = 0;
  state->offered_gw_addr.addr = 0;
  state->offered_bc_addr.addr = 0;

  option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_LEASE_TIME);
  if (option_ptr != NULL)
  {
    state->offered_t0_lease = dhcp_get_option_long(option_ptr + 2);
    state->offered_t1_renew = state->offered_t0_lease / 2;
    state->offered_t2_rebind = state->offered_t0_lease;
  }

  option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_T1);
  if (option_ptr != NULL)
  {
    state->offered_t1_renew = dhcp_get_option_long(option_ptr + 2);
  }
  option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_T2);
  if (option_ptr != NULL)
  {
    state->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2);
  }
  ip_addr_set(&state->offered_ip_addr, &state->msg_in->yiaddr);

  option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_SUBNET_MASK);
  if (option_ptr != NULL)
  {
    state->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
  }

  option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_ROUTER);
  if (option_ptr != NULL)
  {
    state->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
  }

  option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_BROADCAST);
  if (option_ptr != NULL)
  {
    state->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
  }
}
Esempio n. 27
0
static void dhcp_handle_offer(struct dhcp_state *state)
{
  u8_t *option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_SERVER_ID);
  if (option_ptr != NULL)
  {
    state->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
    DEBUGF(DHCP_DEBUG, ("dhcp_handle_offer(): server 0x%08lx\n", state->server_ip_addr.addr));
    /* remember offered address */
    ip_addr_set(&state->offered_ip_addr, (struct ip_addr *)&state->msg_in->yiaddr);
    DEBUGF(DHCP_DEBUG, ("dhcp_handle_offer(): offer for 0x%08lx\n", state->offered_ip_addr.addr));
    dhcp_select(state);
  }
  else
  {
    //dhcp_start(restart);
  }
}
Esempio n. 28
0
/**
 * Change the netmask of a network interface
 *
 * @param netif the network interface to change
 * @param netmask the new netmask
 *
 * @note call if_set_addr() if you also want to change ip address and
 * default gateway
 */
void
if_set_netmask (struct interface *netif, ip_addr_t * netmask)
{
#ifdef CONFIG_OPENSWITCH_TCP_IP
    snmp_delete_iprteidx_tree (0, netif);
#endif
    /* set new netmask to netif */
    ip_addr_set (&(netif->netmask), netmask);
#ifdef CONFIG_OPENSWITCH_TCP_IP
    snmp_insert_iprteidx_tree (0, netif);
#endif
    LWIP_DEBUGF (NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
                 ("netif: netmask of interface %c%c set to %" U16_F ".%" U16_F
                  ".%" U16_F ".%" U16_F "\n", netif->ifDescr[0], netif->ifDescr[1],
                  ip4_addr1_16 (&netif->netmask),
                  ip4_addr2_16 (&netif->netmask),
                  ip4_addr3_16 (&netif->netmask),
                  ip4_addr4_16 (&netif->netmask)));
}
Esempio n. 29
0
/**
 * 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;
}
Esempio n. 30
0
/**
 * Set the state of the connection to be LISTEN, which means that it
 * is able to accept incoming connections. The protocol control block
 * is reallocated in order to consume less memory. Setting the
 * connection to LISTEN is an irreversible process.
 *
 * @param pcb the original tcp_pcb
 * @param backlog the incoming connections queue limit
 * @return tcp_pcb used for listening, consumes less memory.
 *
 * @note The original tcp_pcb is freed. This function therefore has to be
 *       called like this:
 *             tpcb = tcp_listen(tpcb);
 */
struct tcp_pcb *
tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
{
  struct tcp_pcb_listen *lpcb;

  LWIP_UNUSED_ARG(backlog);
  LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);

  /* already listening? */
  if (pcb->state == LISTEN) {
    return pcb;
  }
	/* 分配一个监听状态控制块struct tcp_pcb_listen */
  lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);
  if (lpcb == NULL) {
    return NULL;
  }
	/* 复制各个字段 */
  lpcb->callback_arg = pcb->callback_arg;
  lpcb->local_port = pcb->local_port;
  lpcb->state = LISTEN;
  lpcb->so_options = pcb->so_options;
  lpcb->so_options |= SOF_ACCEPTCONN;
  lpcb->ttl = pcb->ttl;
  lpcb->tos = pcb->tos;
  ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
	/* 从tcp_bound_pcbs链表删除控制块 */
  TCP_RMV(&tcp_bound_pcbs, pcb);
	/* 释放控制块 */
  memp_free(MEMP_TCP_PCB, pcb);
#if LWIP_CALLBACK_API
  lpcb->accept = tcp_accept_null;
#endif /* LWIP_CALLBACK_API */
#if TCP_LISTEN_BACKLOG
  lpcb->accepts_pending = 0;
  lpcb->backlog = (backlog ? backlog : 1);
#endif /* TCP_LISTEN_BACKLOG */
	/* 把新控制块加入tcp_listen_pcbs链表首部 */
  TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
	/* 返回新控制块指针 */
  return (struct tcp_pcb *)lpcb;
}