void*
netPipe_initTcp( void* hwpipe, void* _looper, const char* args )
{
    /* Build SockAddress from arguments. Acceptable formats are:
     *   <port>
     */
    SockAddress  address;
    uint16_t     port;
    void*        ret;

    if (args == NULL) {
        D("%s: Missing address!", __FUNCTION__);
        return NULL;
    }
    D("%s: Port is '%s'", __FUNCTION__, args);

    /* Now, look at the port number */
    {
        char* end;
        long  val = strtol(args, &end, 10);
        if (end == NULL || *end != '\0' || val <= 0 || val > 65535) {
            D("%s: Invalid port number: '%s'", __FUNCTION__, args);
        }
        port = (uint16_t)val;
    }
    sock_address_init_inet(&address, SOCK_ADDRESS_INET_LOOPBACK, port);

    ret = netPipe_initFromAddress(hwpipe, &address, _looper);

    sock_address_done(&address);
    return ret;
}
Exemple #2
0
static void _slirp_redir_loop(void (*func)(void *opaque, int is_udp,
                                           const SockAddress *laddr,
                                           const SockAddress *faddr),
                              void *opaque, int is_udp)
{
    struct socket *head = (is_udp ? &udb : &tcb);
    struct socket *so;

    for (so = head->so_next; so != head; so = so->so_next) {
        SockAddress  local, foreign;
	
		sock_address_init_inet(&local, so->so_laddr_ip, so->so_laddr_port);
		sock_address_init_inet(&foreign, so->so_faddr_ip, so->so_faddr_port);
        func(opaque, is_udp,
             &local, &foreign);
    }
}
Exemple #3
0
int udp_output_(struct socket *so, struct mbuf *m,
               SockAddress* from)
{
    SockAddress  saddr, daddr;
    uint32_t     saddr_ip;
    uint16_t     saddr_port;

    saddr_ip   = sock_address_get_ip(from);
    saddr_port = sock_address_get_port(from);

    if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) {
        saddr_ip = so->so_faddr_ip;
        if ((so->so_faddr_ip & 0x000000ff) == 0xff)
            saddr_ip = alias_addr_ip;
    }

    sock_address_init_inet( &saddr, saddr_ip, saddr_port );
    sock_address_init_inet( &daddr, so->so_laddr_ip, so->so_laddr_port );

    return udp_output2_(so, m, &saddr, &daddr, so->so_iptos);
}
Exemple #4
0
static BOOTPClient *find_addr(SockAddress *paddr, const uint8_t *macaddr)
{
    BOOTPClient *bc;
    int i;

    for(i = 0; i < NB_ADDR; i++) {
        if (!memcmp(macaddr, bootp_clients[i].macaddr, 6))
            goto found;
    }
    return NULL;
 found:
    bc = &bootp_clients[i];
    bc->allocated = 1;
    sock_address_init_inet( paddr,
                            special_addr_ip | (i + START_ADDR),
                            BOOTP_CLIENT );
    return bc;
}
Exemple #5
0
/********************************************************************************
 *                            ADB server API
 *******************************************************************************/
int
adb_server_init(int port)
{
    if (!_adb_server_initialized) {
        /* Initialize the descriptor. */
        memset(&_adb_server, 0, sizeof(_adb_server));
        alist_init(&_adb_server.adb_hosts);
        alist_init(&_adb_server.adb_guests);
        alist_init(&_adb_server.pending_hosts);
        alist_init(&_adb_server.pending_guests);
        _adb_server.port = port;

        /* Create looper for an async I/O on the server. */
        _adb_server.looper = looper_newCore();
        if (_adb_server.looper == NULL) {
            E("Unable to create I/O looper for ADB server");
            return -1;
        }

        /* Create loopback server socket for the ADB port. */
        sock_address_init_inet(&_adb_server.socket_address,
                               SOCK_ADDRESS_INET_LOOPBACK, port);
        _adb_server.so = socket_loopback_server(port, SOCKET_STREAM);
        if (_adb_server.so < 0) {
            E("Unable to create ADB server socket: %s", strerror(errno));
            return -1;
        }

        /* Prepare server socket for I/O */
        socket_set_nonblock(_adb_server.so);
        loopIo_init(_adb_server.io, _adb_server.looper, _adb_server.so,
                    _on_server_socket_io, &_adb_server);
        loopIo_wantRead(_adb_server.io);

        D("ADB server has been initialized for port %d. Socket: %d",
          port, _adb_server.so);

        _adb_server_initialized = 1;
    }

    return 0;
}
Exemple #6
0
/*
 * sendto() a socket
 */
int
sosendto(struct socket *so, struct mbuf *m)
{
	int ret;
    SockAddress   addr;
    uint32_t      addr_ip;
    uint16_t      addr_port;

	DEBUG_CALL("sosendto");
	DEBUG_ARG("so = %lx", (long)so);
	DEBUG_ARG("m = %lx", (long)m);

	if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) {
        /* It's an alias */
      	int  low = so->so_faddr_ip & 0xff;

        if ( CTL_IS_DNS(low) )
            addr_ip = dns_addr[low - CTL_DNS];
        else
            addr_ip = loopback_addr_ip;
	} else
	    addr_ip = so->so_faddr_ip;

	addr_port = so->so_faddr_port;

	/*
	 * test for generic forwarding; this function replaces the arguments
	 * only on success
	 */
	unsigned long faddr = addr_ip;
        int fport = addr_port;

	if (slirp_should_net_forward(faddr, fport, &faddr, &fport)) {
      time_t timestamp = time(NULL);
      slirp_drop_log(
	       "Redirected UDP: src: 0x%08lx:0x%04x org dst: 0x%08lx:0x%04x "
	       "new dst: 0x%08lx:0x%04x %ld\n",
	        so->so_laddr_ip, so->so_laddr_port,
	        addr_ip, addr_port,
	        faddr, fport, timestamp
	    );
	}
	addr_ip = faddr;
	addr_port = fport;


        sock_address_init_inet(&addr, addr_ip, addr_port);

	DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%08x\n", addr_port, addr_ip));

	/* Don't care what port we get */
	ret = socket_sendto(so->s, m->m_data, m->m_len,&addr);
	if (ret < 0)
		return -1;

	/*
	 * Kill the socket if there's no reply in 4 minutes,
	 * but only if it's an expirable socket
	 */
	if (so->so_expire)
		so->so_expire = curtime + SO_EXPIRE;
	so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
	return 0;
}
Exemple #7
0
static void bootp_reply(const struct bootp_t *bp)
{
    BOOTPClient *bc = NULL;
    struct mbuf *m;
    struct bootp_t *rbp;
    SockAddress  saddr, daddr;
    uint32_t     dns_addr;
    const ipaddr_t *preq_addr;
    int dhcp_msg_type, val;
    uint8_t *q;

    /* extract exact DHCP msg type */
    dhcp_decode(bp, &dhcp_msg_type, &preq_addr);
    dprintf("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type);
    if (preq_addr) {
        dprintf(" req_addr=%08x\n", ntohl(*(uint32_t*)preq_addr));
    } else {
        dprintf("\n");
    }
    if (dhcp_msg_type == 0)
        dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */

    if (dhcp_msg_type != DHCPDISCOVER &&
        dhcp_msg_type != DHCPREQUEST)
        return;
    /* XXX: this is a hack to get the client mac address */
    memcpy(client_ethaddr, bp->bp_hwaddr, 6);

    if ((m = m_get()) == NULL)
        return;
    m->m_data += IF_MAXLINKHDR;
    rbp = (struct bootp_t *)m->m_data;
    m->m_data += sizeof(struct udpiphdr);
    memset(rbp, 0, sizeof(struct bootp_t));

    if (dhcp_msg_type == DHCPDISCOVER) {
        if (preq_addr) {
            bc = request_addr(preq_addr, client_ethaddr);
            if (bc) {
				sock_address_init_inet(&daddr, ip_geth(*preq_addr), BOOTP_CLIENT);
            }
        }
        if (!bc) {
         new_addr:
	        bc = get_new_addr(&daddr, client_ethaddr);
            if (!bc) {
                dprintf("no address left\n");
                return;
            }
        }
        memcpy(bc->macaddr, client_ethaddr, 6);
    } else if (preq_addr) {
        bc = request_addr(preq_addr, client_ethaddr);
        if (bc) {
			sock_address_init_inet(&daddr, ip_geth(*preq_addr), BOOTP_CLIENT);
            memcpy(bc->macaddr, client_ethaddr, 6);
        } else {
            sock_address_init_inet(&daddr, 0, BOOTP_CLIENT);
        }
    } else {
        bc = find_addr(&daddr, bp->bp_hwaddr);
        if (!bc) {
            /* if never assigned, behaves as if it was already
               assigned (windows fix because it remembers its address) */
            goto new_addr;
        }
    }

    sock_address_init_inet( &saddr, special_addr_ip | CTL_ALIAS,
                            BOOTP_SERVER );

    rbp->bp_op = BOOTP_REPLY;
    rbp->bp_xid = bp->bp_xid;
    rbp->bp_htype = 1;
    rbp->bp_hlen = 6;
    memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);

    rbp->bp_yiaddr = htonl(sock_address_get_ip(&daddr)); /* Client IP address */
    rbp->bp_siaddr = htonl(sock_address_get_ip(&saddr)); /* Server IP address */

    q = rbp->bp_vend;
    memcpy(q, rfc1533_cookie, 4);
    q += 4;

    if (bc) {
        uint32_t  saddr_ip = htonl(sock_address_get_ip(&saddr));
        dprintf("%s addr=%08x\n",
                (dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed",
                sock_address_get_ip(&daddr));

        if (dhcp_msg_type == DHCPDISCOVER) {
            *q++ = RFC2132_MSG_TYPE;
            *q++ = 1;
            *q++ = DHCPOFFER;
        } else /* DHCPREQUEST */ {
            *q++ = RFC2132_MSG_TYPE;
            *q++ = 1;
            *q++ = DHCPACK;
        }

        if (bootp_filename)
            snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s",
                     bootp_filename);

        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr_ip, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0x00;

        if (!slirp_restrict) {
            *q++ = RFC1533_GATEWAY;
            *q++ = 4;
            memcpy(q, &saddr_ip, 4);
            q += 4;

            *q++ = RFC1533_DNS;
            *q++ = 4;
            dns_addr = htonl(special_addr_ip | CTL_DNS);
            memcpy(q, &dns_addr, 4);
            q += 4;
        }

        *q++ = RFC2132_LEASE_TIME;
        *q++ = 4;
        val = htonl(LEASE_TIME);
        memcpy(q, &val, 4);
        q += 4;

        if (*slirp_hostname) {
            val = strlen(slirp_hostname);
            *q++ = RFC1533_HOSTNAME;
            *q++ = val;
            memcpy(q, slirp_hostname, val);
            q += val;
        }
    } else {
        static const char nak_msg[] = "requested address not available";

        dprintf("nak'ed addr=%08x\n", ip_geth(*preq_addr));

        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        *q++ = DHCPNAK;

        *q++ = RFC2132_MESSAGE;
        *q++ = sizeof(nak_msg) - 1;
        memcpy(q, nak_msg, sizeof(nak_msg) - 1);
        q += sizeof(nak_msg) - 1;
    }
    *q++ = RFC1533_END;

	sock_address_init_inet(&daddr, 0xffffffffu, BOOTP_CLIENT);

    m->m_len = sizeof(struct bootp_t) -
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Exemple #8
0
void
icmp_input(struct mbuf *m, int hlen)
{
  register struct icmp *icp;
  register struct ip *ip=mtod(m, struct ip *);
  int icmplen=ip->ip_len;
  /* int code; */

  DEBUG_CALL("icmp_input");
  DEBUG_ARG("m = %lx", (long )m);
  DEBUG_ARG("m_len = %d", m->m_len);

  STAT(icmpstat.icps_received++);

  /*
   * Locate icmp structure in mbuf, and check
   * that its not corrupted and of at least minimum length.
   */
  if (icmplen < ICMP_MINLEN) {          /* min 8 bytes payload */
    STAT(icmpstat.icps_tooshort++);
  freeit:
    m_freem(m);
    goto end_error;
  }

  m->m_len -= hlen;
  m->m_data += hlen;
  icp = mtod(m, struct icmp *);
  if (cksum(m, icmplen)) {
    STAT(icmpstat.icps_checksum++);
    goto freeit;
  }
  m->m_len += hlen;
  m->m_data -= hlen;

  /*	icmpstat.icps_inhist[icp->icmp_type]++; */
  /* code = icp->icmp_code; */

  DEBUG_ARG("icmp_type = %d", icp->icmp_type);
  switch (icp->icmp_type) {
  case ICMP_ECHO:
    icp->icmp_type = ICMP_ECHOREPLY;
    ip->ip_len += hlen;	             /* since ip_input subtracts this */
    if (ip_geth(ip->ip_dst) == alias_addr_ip) {
      icmp_reflect(m);
    } else {
      struct socket *so;
      SockAddress  addr;
      uint32_t     addr_ip;
      uint16_t     addr_port;

      if ((so = socreate()) == NULL) goto freeit;
      if(udp_attach(so) == -1) {
	DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
		    errno,errno_str));
	sofree(so);
	m_free(m);
	goto end_error;
      }
      so->so_m = m;
      so->so_faddr_ip   = ip_geth(ip->ip_dst);
      so->so_faddr_port = 7;
      so->so_laddr_ip   = ip_geth(ip->ip_src);
      so->so_laddr_port = 9;
      so->so_iptos = ip->ip_tos;
      so->so_type = IPPROTO_ICMP;
      so->so_state = SS_ISFCONNECTED;

      /* Send the packet */
      if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) {
        /* It's an alias */
        int  low = so->so_faddr_ip & 0xff;

        if (low >= CTL_DNS && low < CTL_DNS + dns_addr_count)
            addr_ip = dns_addr[low - CTL_DNS];
        else
            addr_ip = loopback_addr_ip;
      } else {
            addr_ip = so->so_faddr_ip;
      }
      addr_port = so->so_faddr_port;

      sock_address_init_inet( &addr, addr_ip, addr_port );

      if(socket_sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), &addr) < 0) {
        DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
                    errno,errno_str));
        icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,errno_str);
        udp_detach(so);
      }
    } /* if ip->ip_dst.s_addr == alias_addr.s_addr */
    break;
  case ICMP_UNREACH:
    /* XXX? report error? close socket? */
  case ICMP_TIMXCEED:
  case ICMP_PARAMPROB:
  case ICMP_SOURCEQUENCH:
  case ICMP_TSTAMP:
  case ICMP_MASKREQ:
  case ICMP_REDIRECT:
    STAT(icmpstat.icps_notsupp++);
    m_freem(m);
    break;

  default:
    STAT(icmpstat.icps_badtype++);
    m_freem(m);
  } /* swith */

end_error:
  /* m is m_free()'d xor put in a socket xor or given to ip_send */
  return;
}