void send_data_packets() {
  int i;
  struct sockaddr_in* from;
  int retsize, chunk_size;
  int * upload_id_list = get_upload_list(&retsize);
  int * upload_chunk_id_list = get_upload_chunk_list(&chunk_size);
  int peer_id;
  unsigned seq_number;
  int canSend;
  int timeout;
  for(i = 0; i < retsize; i++) {
  	peer_id = upload_id_list[i];
  	canSend = 1;
    /* if timeout send timeout packet first */
    if ((seq_number = get_timeout_seq(peer_id)) == 0) {
    	/* if not timout, check window size */
    	if(get_queue_size(peer_id) < get_cwnd_size(peer_id)) {
				seq_number = get_tail_seq_number(peer_id);
				/* transmit */
				timeout = 0;
			}
    	else{
    		canSend = 0;
      }
    }
    else {
    	/* retransmit */
      printf("retransmit\n");
      window_timeout(peer_id);
    	seq_number -= 1; /* offset by 1 */
    	timeout = 1;
    }
    //printf("seq: %d, canSend: %d, queue: %d, cwnd: %d\n", seq_number, canSend, get_queue_size(peer_id), get_cwnd_size(peer_id));
   	/* send one packet one time to ensure fairness */
    if(canSend && seq_number < MAX_PACKET_PER_CHUNK) {
		  char data[MAX_PAYLOAD_SIZE];
		  struct packet* packet;
		  if(seq_number==MAX_PACKET_PER_CHUNK-1){
		    int last_packet_size = BT_CHUNK_SIZE-MAX_PAYLOAD_SIZE*(MAX_PACKET_PER_CHUNK-1);
		    read_file(master_data_file_name, data, last_packet_size, 
		      upload_chunk_id_list[i] * BT_CHUNK_SIZE + seq_number * MAX_PAYLOAD_SIZE);
		    packet = make_packet(DATA, NULL, data, last_packet_size, seq_number + 1, 0, NULL, NULL, NULL);
		  }else{
		    read_file(master_data_file_name, data, MAX_PAYLOAD_SIZE, 
		      upload_chunk_id_list[i] * BT_CHUNK_SIZE + seq_number * MAX_PAYLOAD_SIZE);
		    packet = make_packet(DATA, NULL, data, MAX_PAYLOAD_SIZE, seq_number + 1, 0, NULL, NULL, NULL);
		  }

		  /* Send DATA */
		  from = find_addr(peer_id);
		  send_packet(*packet, sock, (struct sockaddr*)from);
		  wait_ack(peer_id, seq_number + 1, timeout);
		  free(packet->header);
		  free(packet);
    }
  }
  free(upload_id_list);
  free(upload_chunk_id_list);
}
Esempio n. 2
0
static int handle_forward_disassemble(RCore* core, RList *hits, ut8* buf, ut64 len, ut64 current_buf_pos, ut64 current_instr_addr, ut64 end_addr){
	// forward disassemble from the current instruction up to the end address
	ut64 temp_instr_len = 0,
		temp_instr_addr = current_instr_addr,
		tmp_current_buf_pos = current_buf_pos,
        start = 0,  end = 0,
		start_range = current_instr_addr,
		end_range = end_addr;

    RAsmOp op;
    RCoreAsmHit *hit = NULL, *found_addr = NULL;
    ut8 is_valid = R_FALSE;

	if (end_addr < current_instr_addr)
		return end_addr;

	r_asm_set_pc (core->assembler, current_instr_addr);
	while ( tmp_current_buf_pos < len && temp_instr_addr < end_addr) {
		temp_instr_len = len - tmp_current_buf_pos;
		IFDBG eprintf("Current position: %"PFMT64d" instr_addr: 0x%"PFMT64x"\n", tmp_current_buf_pos, temp_instr_addr);
		temp_instr_len = r_asm_disassemble (core->assembler, &op, buf+tmp_current_buf_pos, temp_instr_len);

		if (temp_instr_len == 0){
			is_valid = R_FALSE;
			temp_instr_len = 1;
		} else
			is_valid = R_TRUE;

		// check to see if addr exits
		found_addr = find_addr(hits, temp_instr_addr);
		start = temp_instr_addr;
		end = temp_instr_addr + temp_instr_len;

		if (!found_addr) {
			add_hit_to_sorted_hits(hits, temp_instr_addr, temp_instr_len, is_valid);
		} else if (is_valid && !found_addr->valid && is_addr_in_range(start, end, start_range, end_range )) {
			ut32 prune_results = 0;
			prune_results = prune_hits_in_addr_range(hits, temp_instr_addr, temp_instr_len, is_valid);
			add_hit_to_sorted_hits(hits, temp_instr_addr, temp_instr_len, is_valid);

			if (prune_results ) {
				r_list_add_sorted (hits, hit, ((RListComparator)rcoreasm_address_comparator));
				IFDBG eprintf("Pruned %u hits from list in fwd sweep.\n", prune_results);
			} else {
				free (hit);
				hit = NULL;
			}
		}

		temp_instr_addr += temp_instr_len;
		tmp_current_buf_pos += temp_instr_len;
	}
	return temp_instr_addr;
}
Esempio n. 3
0
static const char *find_local(MAPS *path, char *ratsign, int rats_offs,
			              char *int_full_key, char *int_bare_key,
		              int query_form, char **extp, char **saved_ext,
			              VSTRING *ext_addr_buf)
{
    const char *myname = "mail_addr_find";
    const char *result;
    int     with_domain;
    int     saved_ch;

    /*
     * This code was ripped from the middle of a function so that it can be
     * reused multiple times, that's why the interface makes little sense.
     */
    with_domain = rats_offs ? WITH_DOMAIN : SANS_DOMAIN;

    saved_ch = *(unsigned char *) (ratsign + rats_offs);
    *(ratsign + rats_offs) = 0;
    result = find_addr(path, int_full_key, PARTIAL, with_domain,
		       query_form, ext_addr_buf);
    *(ratsign + rats_offs) = saved_ch;
    if (result == 0 && path->error == 0 && int_bare_key != 0) {
	if ((ratsign = strrchr(int_bare_key, '@')) == 0)
	    msg_panic("%s: bare key botch", myname);
	saved_ch = *(unsigned char *) (ratsign + rats_offs);
	*(ratsign + rats_offs) = 0;
	if ((result = find_addr(path, int_bare_key, PARTIAL, with_domain,
				query_form, ext_addr_buf)) != 0
	    && extp != 0) {
	    *extp = *saved_ext;
	    *saved_ext = 0;
	}
	*(ratsign + rats_offs) = saved_ch;
    }
    return result;
}
Esempio n. 4
0
void Peers::add_p2p_group_client(QStandardItem * /*parent*/, QString params)
{
	/*
	 * dev=02:b5:64:63:30:63 iface=02:b5:64:63:30:63 dev_capab=0x0
	 * dev_type=1-0050f204-1 dev_name='Wireless Client'
	 * config_methods=0x8c
	 */

	QStringList items =
		params.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
	QString addr = "";
	QString name = "";
	int config_methods = 0;
	QString dev_type;

	for (int i = 0; i < items.size(); i++) {
		QString str = items.at(i);
		int pos = str.indexOf('=') + 1;
		if (str.startsWith("dev_name='"))
			name = str.section('\'', 1, -2);
		else if (str.startsWith("config_methods="))
			config_methods =
				str.section('=', 1).toInt(0, 0);
		else if (str.startsWith("dev="))
			addr = str.mid(pos);
		else if (str.startsWith("dev_type=") && dev_type.isEmpty())
			dev_type = str.mid(pos);
	}

	QStandardItem *item = find_addr(addr);
	if (item)
		return;

	item = new QStandardItem(*default_icon, name);
	if (item) {
		/* TODO: indicate somehow the relationship to the group owner
		 * (parent) */
		item->setData(addr, peer_role_address);
		item->setData(config_methods, peer_role_config_methods);
		item->setData(PEER_TYPE_P2P_CLIENT, peer_role_type);
		if (!dev_type.isEmpty())
			item->setData(dev_type, peer_role_pri_dev_type);
		item->setData(items.join(QString("\n")), peer_role_details);
		item->setToolTip(ItemType(PEER_TYPE_P2P_CLIENT));
		model.appendRow(item);
	}
}
Esempio n. 5
0
/*
 * Create a new node in-memory object and look up the node's addresses.
 */
static struct node *
new_node(const char *name)
{
	struct node *node;

	node = malloc(sizeof(*node));
	if (!node)
		fail(NULL);
	memset(node, 0, sizeof(*node));
	node->name = strdup(name);
	if (!node->name)
		fail(NULL);
	node->weight = 1;
	node->addr = find_addr(name);
	node->nodeid = -1;
	node->outgoing_fd = -1;
	node->connecting_fd = -1;
	return node;
}
Esempio n. 6
0
static int
check_callers(int * cannot)
{
    /*
     * get base addresses of multiarray and python, check if
     * backtrace is in these libraries only calling dladdr if a new max address
     * is found.
     * When after the initial multiarray stack everything is inside python we
     * can elide as no C-API user could have messed up the reference counts.
     * Only check until the python frame evaluation function is found
     * approx 10us overhead for stack size of 10
     *
     * TODO some calls go over scalarmath in umath but we cannot get the base
     * address of it from multiarraymodule as it is not linked against it
     */
    static int init = 0;
    /*
     * measured DSO object memory start and end, if an address is located
     * inside these bounds it is part of that library so we don't need to call
     * dladdr on it (assuming linear memory)
     */
    static void * pos_python_start;
    static void * pos_python_end;
    static void * pos_ma_start;
    static void * pos_ma_end;

    /* known address storage to save dladdr calls */
    static void * py_addr[64];
    static void * pyeval_addr[64];
    static npy_intp n_py_addr = 0;
    static npy_intp n_pyeval = 0;

    void *buffer[NPY_MAX_STACKSIZE];
    int i, nptrs;
    int ok = 0;
    /* cannot determine callers */
    if (init == -1) {
        *cannot = 1;
        return 0;
    }

    nptrs = backtrace(buffer, NPY_MAX_STACKSIZE);
    if (nptrs == 0) {
        /* complete failure, disable elision */
        init = -1;
        *cannot = 1;
        return 0;
    }

    /* setup DSO base addresses, ends updated later */
    if (NPY_UNLIKELY(init == 0)) {
        Dl_info info;
        /* get python base address */
        if (dladdr(&PyNumber_Or, &info)) {
            pos_python_start = info.dli_fbase;
            pos_python_end = info.dli_fbase;
        }
        else {
            init = -1;
            return 0;
        }
        /* get multiarray base address */
        if (dladdr(&PyArray_SetNumericOps, &info)) {
            pos_ma_start = info.dli_fbase;
            pos_ma_end = info.dli_fbase;
        }
        else {
            init = -1;
            return 0;
        }
        init = 1;
    }

    /* loop over callstack addresses to check if they leave numpy or cpython */
    for (i = 0; i < nptrs; i++) {
        Dl_info info;
        int in_python = 0;
        int in_multiarray = 0;
#if NPY_ELIDE_DEBUG >= 2
        dladdr(buffer[i], &info);
        printf("%s(%p) %s(%p)\n", info.dli_fname, info.dli_fbase,
               info.dli_sname, info.dli_saddr);
#endif

        /* check stored DSO boundaries first */
        if (buffer[i] >= pos_python_start && buffer[i] <= pos_python_end) {
            in_python = 1;
        }
        else if (buffer[i] >= pos_ma_start && buffer[i] <= pos_ma_end) {
            in_multiarray = 1;
        }

        /* update DSO boundaries via dladdr if necessary */
        if (!in_python && !in_multiarray) {
            if (dladdr(buffer[i], &info) == 0) {
                init = -1;
                ok = 0;
                break;
            }
            /* update DSO end */
            if (info.dli_fbase == pos_python_start) {
                pos_python_end = NPY_NUMBER_MAX(buffer[i], pos_python_end);
                in_python = 1;
            }
            else if (info.dli_fbase == pos_ma_start) {
                pos_ma_end = NPY_NUMBER_MAX(buffer[i], pos_ma_end);
                in_multiarray = 1;
            }
        }

        /* no longer in ok libraries and not reached PyEval -> no elide */
        if (!in_python && !in_multiarray) {
            ok = 0;
            break;
        }

        /* in python check if the frame eval function was reached */
        if (in_python) {
            /* if reached eval we are done */
            if (find_addr(pyeval_addr, n_pyeval, buffer[i])) {
                ok = 1;
                break;
            }
            /*
             * check if its some other function, use pointer lookup table to
             * save expensive dladdr calls
             */
            if (find_addr(py_addr, n_py_addr, buffer[i])) {
                continue;
            }

            /* new python address, check for PyEvalFrame */
            if (dladdr(buffer[i], &info) == 0) {
                init = -1;
                ok = 0;
                break;
            }
            if (info.dli_sname &&
                    strcmp(info.dli_sname, PYFRAMEEVAL_FUNC) == 0) {
                if (n_pyeval < sizeof(pyeval_addr) / sizeof(pyeval_addr[0])) {
                    /* store address to not have to dladdr it again */
                    pyeval_addr[n_pyeval++] = buffer[i];
                }
                ok = 1;
                break;
            }
            else if (n_py_addr < sizeof(py_addr) / sizeof(py_addr[0])) {
                /* store other py function to not have to dladdr it again */
                py_addr[n_py_addr++] = buffer[i];
            }
        }
    }

    /* all stacks after numpy are from python, we can elide */
    if (ok) {
        *cannot = 0;
        return 1;
    }
    else {
#if NPY_ELIDE_DEBUG != 0
        puts("cannot elide due to c-api usage");
#endif
        *cannot = 1;
        return 0;
    }
}
Esempio n. 7
0
static void bootp_reply(struct bootp_t *bp)
{
    BOOTPClient *bc;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    struct in_addr dns_addr;
    int dhcp_msg_type, val;
    uint8_t *q;

    /* extract exact DHCP msg type */
    dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);
    dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type);
    
    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) {
    new_addr:
        bc = get_new_addr(&daddr.sin_addr);
        if (!bc) {
            dprintf("no address left\n");
            return;
        }
        memcpy(bc->macaddr, client_ethaddr, 6);
    } else {
        bc = find_addr(&daddr.sin_addr, 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;
        }
    }

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

    dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr));

    saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    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 = daddr.sin_addr; /* Client IP address */
    rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */

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

    if (dhcp_msg_type == DHCPDISCOVER) {
        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        *q++ = DHCPOFFER;
    } else if (dhcp_msg_type == DHCPREQUEST) {
        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        *q++ = DHCPACK;
    }
        
    if (dhcp_msg_type == DHCPDISCOVER ||
        dhcp_msg_type == DHCPREQUEST) {
        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0x00;
        
        *q++ = RFC1533_GATEWAY;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;
        
        *q++ = RFC1533_DNS;
        *q++ = 4;
        dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | 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;
        }
    }
    *q++ = RFC1533_END;
    
    m->m_len = sizeof(struct bootp_t) - 
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Esempio n. 8
0
int
launch_new_query(struct author *author/*, int idrowback*/)
{
    int new_query = 0, i, start, end, ret;
    mbuf_type *mbuf;
    struct timeval tv;
    uint64_t msnow = 0;
    int slotoff, typeoff;
    start = author->start;
    end = author->end;
    gettimeofday(&tv, NULL);
    msnow = tv.tv_sec * 1000 + tv.tv_usec / 1000;
    for (i = start; i < end; i++) {
        slotoff = 0;
        typeoff = 0;
        mbuf = NULL;
        ret = htable_find_list_io(author->s->qlist, i, slotoff, &typeoff, (uchar **)&mbuf);
        while (ret >= 0)
        {
            if (ret > 0)
            {
                if (mbuf->qtimes > MAX_TRY_TIMES/* || (msnow - mbuf->stime) > 5000*/)
                {
                    release_qoutinfo(author, mbuf, GET_AID(i, typeoff));
                }
                else
                {
                    if (mbuf->stat == NEW_QUERY)
                    {
                        assert(i < QLIST_TABLE_SIZE && typeoff < SUPPORT_TYPE_NUM);
                        mbuf->aid = GET_AID(i, typeoff);   //start id
                        mbuf->backid = mbuf->aid;
                        mbuf->mxtry = 0;
                        if (mbuf->fd != -1)
                            mbuf->fd = author->cudp;
                        mbuf->tdbuffer = author->tdbuffer;
                        mbuf->tempbuffer = author->tempbuffer;
                        mbuf->dmbuffer = author->dmbuffer;
                        mbuf->ipbuffer = author->ipbuffer;
                        new_query++;
                        mbuf->stat = PROCESS_QUERY;
                    }
                    if ((msnow - mbuf->stime) > 1000 && (mbuf->sq == 0))
                    {
                        mbuf->sq = 1;
                    }
                    if ((mbuf->socktype == UDP) && (mbuf->sq == 1)) {
                        ret =
                            find_addr(author->s->forward, author->s->datasets, mbuf,
                                    author->ip, author->s->is_forward);
                        if (mbuf->stat == PROCESS_QUERY && ret == 0)
                            query_from_auth_server(mbuf, author);
                        mbuf->qtimes++;
//                         mbuf->stime = msnow;
                    }
                }
                
            }
            if (ret == 0 || (typeoff == (SUPPORT_TYPE_NUM- 1)))
            {
                slotoff++;
                typeoff = 0;
            }
            else
                typeoff++;
            
            mbuf = NULL;
            ret = htable_find_list_io(author->s->qlist, i, slotoff, &typeoff, (uchar **)&mbuf);
        }
    }

    return new_query;
}
Esempio n. 9
0
File: bootp.c Progetto: 0-14N/NDroid
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);
}
Esempio n. 10
0
static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
{
    BOOTPClient *bc = NULL;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    const struct in_addr *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(preq_addr->s_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(slirp->client_ethaddr, bp->bp_hwaddr, 6);

    m = m_get(slirp);
    if (!m) {
        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(slirp, preq_addr, slirp->client_ethaddr);
            if (bc) {
                daddr.sin_addr = *preq_addr;
            }
        }
        if (!bc) {
         new_addr:
            bc = get_new_addr(slirp, &daddr.sin_addr, slirp->client_ethaddr);
            if (!bc) {
                DPRINTF("no address left\n");
                return;
            }
        }
        memcpy(bc->macaddr, slirp->client_ethaddr, 6);
    } else if (preq_addr) {
        bc = request_addr(slirp, preq_addr, slirp->client_ethaddr);
        if (bc) {
            daddr.sin_addr = *preq_addr;
            memcpy(bc->macaddr, slirp->client_ethaddr, 6);
        } else {
            daddr.sin_addr.s_addr = 0;
        }
    } else {
        bc = find_addr(slirp, &daddr.sin_addr, 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;
        }
    }

    saddr.sin_addr = slirp->vhost_addr;
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    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 = daddr.sin_addr; /* Client IP address */
    rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */

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

    if (bc) {
        DPRINTF("%s addr=%08x\n",
                (dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed",
                ntohl(daddr.sin_addr.s_addr));

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

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

        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        memcpy(q, &slirp->vnetwork_mask, 4);
        q += 4;

        if (!slirp->restricted) {
            *q++ = RFC1533_GATEWAY;
            *q++ = 4;
            memcpy(q, &saddr.sin_addr, 4);
            q += 4;

            *q++ = RFC1533_DNS;
            *q++ = 4;
            memcpy(q, &slirp->vnameserver_addr, 4);
            q += 4;
        }

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

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

        DPRINTF("nak'ed addr=%08x\n", ntohl(preq_addr->s_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;

    daddr.sin_addr.s_addr = 0xffffffffu;

    m->m_len = sizeof(struct bootp_t) -
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Esempio n. 11
0
static void bootp_reply(struct bootp_t *bp)
{
    BOOTPClient *bc;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    struct in_addr dns_addr;
    int reply_type = 0;
    int dhcp_msg_type, val;
    int no_address_assigned;
    uint8_t *q;

    /* extract exact DHCP msg type */
    dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);
    dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type);
    
    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));

    no_address_assigned = 0;
    if (dhcp_msg_type == DHCPDISCOVER) {
        bc = get_new_addr(&daddr.sin_addr);
        if (!bc) {
            dprintf("no address left\n");
            return;
        }
        memcpy(bc->macaddr, client_ethaddr, 6);
    } else {
        bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
        if (!bc) {
            dprintf("no address assigned\n");
            dprintf("sending NAK\n");
	    no_address_assigned = 1;
        }
    }
    dprintf("offered addr=%08x\n", (unsigned int)ntohl(daddr.sin_addr.s_addr));

    saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    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 = daddr.sin_addr; /* IP address */

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

    if (dhcp_msg_type == DHCPDISCOVER) {
        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        *q++ = reply_type = DHCPOFFER;
    } else if (dhcp_msg_type == DHCPREQUEST) {
        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
	if (no_address_assigned)
		reply_type = DHCPNAK;
	else
		reply_type = DHCPACK;
        *q++ = reply_type;
    } 
        
    if ((reply_type != DHCPNAK) && 
	(dhcp_msg_type == DHCPDISCOVER ||
	 dhcp_msg_type == DHCPREQUEST)) {
        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0x00;
        
        *q++ = RFC1533_GATEWAY;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;
        
        *q++ = RFC1533_DNS;
        *q++ = 4;
        dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | 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;
    }
    *q++ = RFC1533_END;
    
    m->m_len = sizeof(struct bootp_t) - 
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Esempio n. 12
0
/*
  Search missing addresses for targets.

  We make serialized queries so we don't need
  to keep more than one query reference (walk_query).
 */
void *_ruli_srv_answer_walk(ruli_srv_t *srv_qry)
{
  ruli_list_t *srv_list     = &srv_qry->answer_srv_list;
  int         srv_list_size = ruli_list_size(srv_list);

  /* Have the user disabled walk query? */
  if (srv_qry->srv_options & RULI_RES_OPT_SRV_NOWALK)
    return query_done(srv_qry, RULI_SRV_CODE_OK);

  /*
   * Scan SRV answer targets, considering address lists
   */
  for (; srv_qry->under.walk_index < srv_list_size; 
       ++srv_qry->under.walk_index) {
    ruli_srv_entry_t *entry = \
      (ruli_srv_entry_t *) ruli_list_get(srv_list, 
					 srv_qry->under.walk_index);
    ruli_list_t *addr_list = &entry->addr_list;
    walk_t *walk_qry;

    /* If this target already has address(es), skip it */
    if (find_addr(addr_list, srv_qry->srv_options))
      continue;

#ifdef RULI_SRV_DEBUG
    {
      char target_txt[RULI_LIMIT_DNAME_TEXT_BUFSZ];
      int  target_txt_len;
      int  result;
      
      result = ruli_dname_decode(target_txt, RULI_LIMIT_DNAME_TEXT_BUFSZ, 
				 &target_txt_len, entry->target, 
				 entry->target_len);
      assert(!result);
      
      fprintf(stderr, 
	      "DEBUG: _ruli_srv_answer_walk(): "
              "missing target=%s walk_index=%d\n", 
	      target_txt, srv_qry->under.walk_index);
    }
#endif
    
    /*
     * Allocate space for auxiliary walk query
     */
    walk_qry = \
      (walk_t *) ruli_malloc(sizeof(*walk_qry));
    if (!walk_qry)
      return query_done(srv_qry, RULI_SRV_CODE_WALK_OTHER);
    walk_qry->srv_query = srv_qry;

    /*
     * Initialize walk query arguments
     */
    walk_qry->walk_query.host_resolver        = srv_qry->srv_resolver;
    walk_qry->walk_query.host_on_answer       = on_walk_answer;
    walk_qry->walk_query.host_on_answer_arg   = walk_qry;
    walk_qry->walk_query.host_domain          = entry->target;
    walk_qry->walk_query.host_domain_len      = entry->target_len;
    walk_qry->walk_query.host_options         = srv_qry->srv_options;
    /* RFC 2782 states CNAME aren't valid SRV targets */
    walk_qry->walk_query.host_max_cname_depth =
	(srv_qry->srv_options & RULI_RES_OPT_SRV_CNAME) ?
	RULI_LIMIT_CNAME_DEPTH : 0;

    /*
     * Submit walk query
     */
    if (ruli_host_query_submit(&walk_qry->walk_query)) {
      ruli_free(walk_qry);
      return query_done(srv_qry, RULI_SRV_CODE_WALK_QUERY);
    }

    /* Wait answer */
    return OOP_CONTINUE;

  } /* for */

  /*
   * All targets scanned, we're done
   */

  return query_done(srv_qry, RULI_SRV_CODE_OK);
}
Esempio n. 13
0
File: expr.c Progetto: ShijianXu/ICS
uint32_t eval(int p,int q)
{
	expr_ok=true;

	int dominant=0;
//printf("%d %d\n",p,q);
	if(p>q){
		printf("This is a bad expression\n");
		expr_ok=false;
		return 0;
	}
	else if(p==q){
		if(tokens[p].type==NUMBER)
			return atoi(tokens[p].str);
		else if(tokens[p].type==HEX)
		{
			char *hexnum=tokens[p].str+2;
			uint32_t sum=0,temp=0;
			int i;
			for(i=0;hexnum[i]!='\0';i++)
			{
				if(hexnum[i]>='0' && hexnum[i]<='9')
					temp=hexnum[i]-'0';
				else if(hexnum[i]>='a' && hexnum[i]<='f')
					temp=hexnum[i]-'a'+10;
				sum=sum*16+temp;
			}
			return sum; 
		}

		/*************** VAR NOT DONE **********************/
		else if(tokens[p].type==VAR)
		{
			uint32_t addr=0;
			addr=find_addr(tokens[p].str,&is_obj);
			if(!is_obj)
				printf("NO SUCH OBJECT!\n");
			return addr;
//printf("test %2x\n",addr);
		}
		/*************** VAR NOT DONE **********************/

		else if(tokens[p].type==REG)
		{

			reg_right=true;

			if(strcmp(tokens[p].str,"$eax")==0)
				return cpu.eax;
			else if(strcmp(tokens[p].str,"$ecx")==0)
				return cpu.ecx;
			else if(strcmp(tokens[p].str,"$edx")==0)
				return cpu.edx;
			else if(strcmp(tokens[p].str,"$ebx")==0)
				return cpu.ebx;
			else if(strcmp(tokens[p].str,"$esp")==0)
				return cpu.esp;
			else if(strcmp(tokens[p].str,"$ebp")==0)
				return cpu.ebp;
			else if(strcmp(tokens[p].str,"$esi")==0)
				return cpu.esi;
			else if(strcmp(tokens[p].str,"$edi")==0)
				return cpu.edi;
			else if(strcmp(tokens[p].str,"$eip")==0)
				return cpu.eip;

			else 
			{
				printf("NO SUCH REGISTER!\n");
				expr_ok=false;
				reg_right=false;
				return 0;
			}
		}
		else if(tokens[p].type==SREG)
		{
			if(strcmp(tokens[p].str,"$ES")==0)
				return cpu.sreg[0].Sreg;
			else if(strcmp(tokens[p].str,"$CS")==0)
				return cpu.sreg[1].Sreg;
			else if(strcmp(tokens[p].str,"$SS")==0)
				return cpu.sreg[2].Sreg;
			else if(strcmp(tokens[p].str,"$DS")==0)
				return cpu.sreg[3].Sreg;
			else
			{
				printf("A Bad expression!\n");
				expr_ok=false;
				return 0;
	        }
		}
		else if(tokens[p].type==EFLAGS)
		{
			if(strcmp(tokens[p].str,"$OF")==0)
				return cpu.OF;
			else if(strcmp(tokens[p].str,"$SF")==0)
				return cpu.SF;
			else if(strcmp(tokens[p].str,"$ZF")==0)
				return cpu.ZF;
			else if(strcmp(tokens[p].str,"$AF")==0)
				return cpu.AF;
			else if(strcmp(tokens[p].str,"$PF")==0)
				return cpu.PF;
			else if(strcmp(tokens[p].str,"$CF")==0)
				return cpu.CF;
		}
		else
		{
			printf("A Bad expression!\n");
			expr_ok=false;
			return 0;
		}
	}
	bool check=check_parentheses(p,q);
	if(!check)
	{
		printf("The parentheses not match!\n");
		expr_ok=false;
		return 0;
	}
	else if(check)
	{
			bool legal;
			legal=check_legal(p,q);
		if(legal)
			return eval(p+1,q-1);		
		else
		{
			dominant=find_domiop(p,q);
			if(tokens[dominant].type==LOGNOT)
			{
				int val3=eval(dominant+1,q);
				return !val3;
			}
			else if(tokens[dominant].type==DEREF)
			{
				int val4=eval(dominant+1,q);
				uint32_t value=swaddr_read(val4,4,3);
				return value;
			}
			else
			{		
				int val1=eval(p,dominant-1);
				if(expr_ok==false)
					return 0;
				int val2=eval(dominant+1,q);
				if(expr_ok==false)
					return 0;
				switch(tokens[dominant].type)
				{
					case '+':return val1+val2;
					case '-':return val1-val2;
					case '*':return val1*val2;
					case '/':return val1/val2;
					case EQ:return val1==val2;
					case NEQ:return val1!=val2;
					case LOGAND:return val1&&val2;
					case LOGOR:return val1||val2;
					default: assert(0);
				}
			}
		}

	}

	return 0;
}
Esempio n. 14
0
const char *mail_addr_find_opt(MAPS *path, const char *address, char **extp,
			               int in_form, int query_form,
			               int out_form, int strategy)
{
    const char *myname = "mail_addr_find";
    VSTRING *ext_addr_buf = 0;
    VSTRING *int_addr_buf = 0;
    const char *int_addr;
    static VSTRING *int_result = 0;
    const char *result;
    char   *ratsign = 0;
    char   *int_full_key;
    char   *int_bare_key;
    char   *saved_ext;
    int     rc = 0;

    /*
     * Optionally convert the address from external form.
     */
    if (in_form == MA_FORM_EXTERNAL) {
	int_addr_buf = vstring_alloc(100);
	unquote_822_local(int_addr_buf, address);
	int_addr = STR(int_addr_buf);
    } else {
	int_addr = address;
    }
    if (query_form == MA_FORM_EXTERNAL_FIRST
	|| query_form == MA_FORM_EXTERNAL)
	ext_addr_buf = vstring_alloc(100);

    /*
     * Initialize.
     */
    int_full_key = mystrdup(int_addr);
    if (*var_rcpt_delim == 0 || (strategy & MA_FIND_NOEXT) == 0) {
	int_bare_key = saved_ext = 0;
    } else {
	/* XXX This could be done after user+foo@domain fails. */
	int_bare_key =
	    strip_addr_internal(int_full_key, &saved_ext, var_rcpt_delim);
    }

    /*
     * Try user+foo@domain and user@domain.
     */
    if ((strategy & MA_FIND_FULL) != 0) {
	result = find_addr(path, int_full_key, FULL, WITH_DOMAIN,
			   query_form, ext_addr_buf);
    } else {
	result = 0;
	path->error = 0;
    }

    if (result == 0 && path->error == 0 && int_bare_key != 0
	&& (result = find_addr(path, int_bare_key, PARTIAL, WITH_DOMAIN,
			       query_form, ext_addr_buf)) != 0
	&& extp != 0) {
	*extp = saved_ext;
	saved_ext = 0;
    }

    /*
     * Try user+foo if the domain matches user+foo@$myorigin,
     * user+foo@$mydestination or user+foo@[${proxy,inet}_interfaces]. Then
     * try with +foo stripped off.
     */
    if (result == 0 && path->error == 0
	&& (ratsign = strrchr(int_full_key, '@')) != 0
	&& (strategy & (MA_FIND_LOCALPART_IF_LOCAL
			| MA_FIND_LOCALPART_AT_IF_LOCAL)) != 0) {
	if (strcasecmp_utf8(ratsign + 1, var_myorigin) == 0
	    || (rc = resolve_local(ratsign + 1)) > 0) {
	    if ((strategy & MA_FIND_LOCALPART_IF_LOCAL) != 0)
		result = find_local(path, ratsign, 0, int_full_key,
				 int_bare_key, query_form, extp, &saved_ext,
				    ext_addr_buf);
	    if (result == 0 && path->error == 0
		&& (strategy & MA_FIND_LOCALPART_AT_IF_LOCAL) != 0)
		result = find_local(path, ratsign, 1, int_full_key,
				 int_bare_key, query_form, extp, &saved_ext,
				    ext_addr_buf);
	} else if (rc < 0)
	    path->error = rc;
    }

    /*
     * Try @domain.
     */
    if (result == 0 && path->error == 0 && ratsign != 0
	&& (strategy & MA_FIND_AT_DOMAIN) != 0)
	result = maps_find(path, ratsign, PARTIAL);

    /*
     * Try domain (optionally, subdomains).
     */
    if (result == 0 && path->error == 0 && ratsign != 0
	&& (strategy & MA_FIND_DOMAIN) != 0) {
	const char *name;
	const char *next;

	if ((strategy & MA_FIND_PDMS) && (strategy & MA_FIND_PDDMDS))
	    msg_warn("mail_addr_find_opt: do not specify both "
		     "MA_FIND_PDMS and MA_FIND_PDDMDS");
	for (name = ratsign + 1; *name != 0; name = next) {
	    if ((result = maps_find(path, name, PARTIAL)) != 0
		|| path->error != 0
		|| (strategy & (MA_FIND_PDMS | MA_FIND_PDDMDS)) == 0
		|| (next = strchr(name + 1, '.')) == 0)
		break;
	    if ((strategy & MA_FIND_PDDMDS) == 0)
		next++;
	}
    }

    /*
     * Try localpart@ even if the domain is not local.
     */
    if ((strategy & MA_FIND_LOCALPART_AT) != 0 \
	&&result == 0 && path->error == 0)
	result = find_local(path, ratsign, 1, int_full_key,
			    int_bare_key, query_form, extp, &saved_ext,
			    ext_addr_buf);

    /*
     * Optionally convert the result to internal form. The lookup result is
     * supposed to be one external-form email address.
     */
    if (result != 0 && out_form == MA_FORM_INTERNAL) {
	if (int_result == 0)
	    int_result = vstring_alloc(100);
	unquote_822_local(int_result, result);
	result = STR(int_result);
    }

    /*
     * Clean up.
     */
    if (msg_verbose)
	msg_info("%s: %s -> %s", myname, address,
		 result ? result :
		 path->error ? "(try again)" :
		 "(not found)");
    myfree(int_full_key);
    if (int_bare_key)
	myfree(int_bare_key);
    if (saved_ext)
	myfree(saved_ext);
    if (int_addr_buf)
	vstring_free(int_addr_buf);
    if (ext_addr_buf)
	vstring_free(ext_addr_buf);
    return (result);
}
Esempio n. 15
0
static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
{
    BOOTPClient *bc = NULL;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    struct in_addr preq_addr;
    int dhcp_msg_type, val;
    uint8_t *q;
    uint8_t *end;
    uint8_t client_ethaddr[ETH_ALEN];

    /* 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.s_addr != htonl(0L))
        DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_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;

    /* Get client's hardware address from bootp request */
    memcpy(client_ethaddr, bp->bp_hwaddr, ETH_ALEN);

    m = m_get(slirp);
    if (!m) {
        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.s_addr != htonl(0L)) {
            bc = request_addr(slirp, &preq_addr, client_ethaddr);
            if (bc) {
                daddr.sin_addr = preq_addr;
            }
        }
        if (!bc) {
         new_addr:
            bc = get_new_addr(slirp, &daddr.sin_addr, client_ethaddr);
            if (!bc) {
                DPRINTF("no address left\n");
                return;
            }
        }
        memcpy(bc->macaddr, client_ethaddr, ETH_ALEN);
    } else if (preq_addr.s_addr != htonl(0L)) {
        bc = request_addr(slirp, &preq_addr, client_ethaddr);
        if (bc) {
            daddr.sin_addr = preq_addr;
            memcpy(bc->macaddr, client_ethaddr, ETH_ALEN);
        } else {
            /* DHCPNAKs should be sent to broadcast */
            daddr.sin_addr.s_addr = 0xffffffff;
        }
    } else {
        bc = find_addr(slirp, &daddr.sin_addr, 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;
        }
    }

    /* Update ARP table for this IP address */
    arp_table_add(slirp, daddr.sin_addr.s_addr, client_ethaddr);

    saddr.sin_addr = slirp->vhost_addr;
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    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, ETH_ALEN);

    rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
    rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */

    q = rbp->bp_vend;
    end = (uint8_t *)&rbp[1];
    memcpy(q, rfc1533_cookie, 4);
    q += 4;

    if (bc) {
        DPRINTF("%s addr=%08" PRIx32 "\n",
                (dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed",
                ntohl(daddr.sin_addr.s_addr));

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

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

        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        memcpy(q, &slirp->vnetwork_mask, 4);
        q += 4;

        if (!slirp->restricted) {
            *q++ = RFC1533_GATEWAY;
            *q++ = 4;
            memcpy(q, &saddr.sin_addr, 4);
            q += 4;

            *q++ = RFC1533_DNS;
            *q++ = 4;
            memcpy(q, &slirp->vnameserver_addr, 4);
            q += 4;
        }

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

        if (*slirp->client_hostname) {
            val = strlen(slirp->client_hostname);
            if (q + val + 2 >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting host name option.");
            } else {
                *q++ = RFC1533_HOSTNAME;
                *q++ = val;
                memcpy(q, slirp->client_hostname, val);
                q += val;
            }
        }

        if (slirp->vdomainname) {
            val = strlen(slirp->vdomainname);
            if (q + val + 2 >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting domain name option.");
            } else {
                *q++ = RFC1533_DOMAINNAME;
                *q++ = val;
                memcpy(q, slirp->vdomainname, val);
                q += val;
            }
        }

        if (slirp->tftp_server_name) {
            val = strlen(slirp->tftp_server_name);
            if (q + val + 2 >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting tftp-server-name option.");
            } else {
                *q++ = RFC2132_TFTP_SERVER_NAME;
                *q++ = val;
                memcpy(q, slirp->tftp_server_name, val);
                q += val;
            }
        }

        if (slirp->vdnssearch) {
            val = slirp->vdnssearch_len;
            if (q + val >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting domain-search option.");
            } else {
                memcpy(q, slirp->vdnssearch, val);
                q += val;
            }
        }
    } else {
        static const char nak_msg[] = "requested address not available";

        DPRINTF("nak'ed addr=%08" PRIx32 "\n", ntohl(preq_addr.s_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;
    }
    assert(q < end);
    *q = RFC1533_END;

    daddr.sin_addr.s_addr = 0xffffffffu;

    m->m_len = sizeof(struct bootp_t) -
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Esempio n. 16
0
static void bootp_reply(const struct bootp_t *bp)
{
    BOOTPClient *bc = NULL;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    struct in_addr dns_addr;
    const struct in_addr *preq_addr;
    int dhcp_msg_type, val;
    uint8_t *q;

    
    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(preq_addr->s_addr));
    else
        dprintf("\n");

    if (dhcp_msg_type == 0)
        dhcp_msg_type = DHCPREQUEST; 

    if (dhcp_msg_type != DHCPDISCOVER &&
        dhcp_msg_type != DHCPREQUEST)
        return;
    
    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) {
                daddr.sin_addr = *preq_addr;
            }
        }
        if (!bc) {
         new_addr:
            bc = get_new_addr(&daddr.sin_addr, 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) {
            daddr.sin_addr = *preq_addr;
            memcpy(bc->macaddr, client_ethaddr, 6);
        } else {
            daddr.sin_addr.s_addr = 0;
        }
    } else {
        bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
        if (!bc) {
            goto new_addr;
        }
    }

    saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    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 = daddr.sin_addr; 
    rbp->bp_siaddr = saddr.sin_addr; 

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

    if (bc) {
        dprintf("%s addr=%08x\n",
                (dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed",
                ntohl(daddr.sin_addr.s_addr));

        if (dhcp_msg_type == DHCPDISCOVER) {
            *q++ = RFC2132_MSG_TYPE;
            *q++ = 1;
            *q++ = DHCPOFFER;
        } else  {
            *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.sin_addr, 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.sin_addr, 4);
            q += 4;

            *q++ = RFC1533_DNS;
            *q++ = 4;
            dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | 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", ntohl(preq_addr->s_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;

    daddr.sin_addr.s_addr = 0xffffffffu;

    m->m_len = sizeof(struct bootp_t) -
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Esempio n. 17
0
void Peers::event_notify(WpaMsg msg)
{
	QString text = msg.getMsg();

	if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
		/*
		 * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
		 * 02:2a:c4:18:5b:f3
		 * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
		 */
		QStringList items = text.split(' ');
		QString uuid = items[1];
		QString addr = items[2];
		QString name = "";

		QStandardItem *item = find_addr(addr);
		if (item)
			return;

		int pos = text.indexOf('[');
		if (pos >= 0) {
			int pos2 = text.lastIndexOf(']');
			if (pos2 >= pos) {
				items = text.mid(pos + 1, pos2 - pos - 1).
					split('|');
				name = items[0];
				items.append(addr);
			}
		}

		item = new QStandardItem(*laptop_icon, name);
		if (item) {
			item->setData(addr, peer_role_address);
			item->setData(PEER_TYPE_WPS_PIN_NEEDED,
				      peer_role_type);
			item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
			item->setData(items.join("\n"), peer_role_details);
			item->setData(items[5], peer_role_pri_dev_type);
			model.appendRow(item);
		}
		return;
	}

	if (text.startsWith(AP_STA_CONNECTED)) {
		/* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
		QStringList items = text.split(' ');
		QString addr = items[1];
		QStandardItem *item = find_addr(addr);
		if (item == NULL || item->data(peer_role_type).toInt() !=
		    PEER_TYPE_ASSOCIATED_STATION)
			add_single_station(addr.toAscii().constData());
		return;
	}

	if (text.startsWith(AP_STA_DISCONNECTED)) {
		/* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
		QStringList items = text.split(' ');
		QString addr = items[1];

		if (model.rowCount() == 0)
			return;

		QModelIndexList lst = model.match(model.index(0, 0),
						  peer_role_address, addr, -1);
		for (int i = 0; i < lst.size(); i++) {
			QStandardItem *item = model.itemFromIndex(lst[i]);
			if (item && item->data(peer_role_type).toInt() ==
			    PEER_TYPE_ASSOCIATED_STATION) {
				model.removeRow(lst[i].row());
				break;
			}
		}
		return;
	}

	if (text.startsWith(P2P_EVENT_DEVICE_FOUND)) {
		/*
		 * P2P-DEVICE-FOUND 02:b5:64:63:30:63
		 * p2p_dev_addr=02:b5:64:63:30:63 pri_dev_type=1-0050f204-1
		 * name='Wireless Client' config_methods=0x84 dev_capab=0x21
		 * group_capab=0x0
		 */
		QStringList items =
			text.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
		QString addr = items[1];
		QString name = "";
		QString pri_dev_type;
		int config_methods = 0;
		for (int i = 0; i < items.size(); i++) {
			QString str = items.at(i);
			if (str.startsWith("name='"))
				name = str.section('\'', 1, -2);
			else if (str.startsWith("config_methods="))
				config_methods =
					str.section('=', 1).toInt(0, 0);
			else if (str.startsWith("pri_dev_type="))
				pri_dev_type = str.section('=', 1);
		}

		QStandardItem *item = find_addr(addr);
		if (item) {
			int type = item->data(peer_role_type).toInt();
			if (type == PEER_TYPE_P2P)
				return;
		}

		item = new QStandardItem(*default_icon, name);
		if (item) {
			item->setData(addr, peer_role_address);
			item->setData(config_methods,
				      peer_role_config_methods);
			item->setData(PEER_TYPE_P2P, peer_role_type);
			if (!pri_dev_type.isEmpty())
				item->setData(pri_dev_type,
					      peer_role_pri_dev_type);
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			item->setToolTip(ItemType(PEER_TYPE_P2P));
			model.appendRow(item);
		}

		item = find_addr_type(addr,
				      PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT);
		if (item)
			item->setBackground(Qt::NoBrush);
	}

	if (text.startsWith(P2P_EVENT_GROUP_STARTED)) {
		/* P2P-GROUP-STARTED wlan0-p2p-0 GO ssid="DIRECT-3F"
		 * passphrase="YOyTkxID" go_dev_addr=02:40:61:c2:f3:b7
		 * [PERSISTENT] */
		QStringList items = text.split(' ');
		if (items.size() < 4)
			return;

		int pos = text.indexOf(" ssid=\"");
		if (pos < 0)
			return;
		QString ssid = text.mid(pos + 7);
		pos = ssid.indexOf(" passphrase=\"");
		if (pos < 0)
			pos = ssid.indexOf(" psk=");
		if (pos >= 0)
			ssid.truncate(pos);
		pos = ssid.lastIndexOf('"');
		if (pos >= 0)
			ssid.truncate(pos);

		QStandardItem *item = new QStandardItem(*group_icon, ssid);
		if (item) {
			item->setData(PEER_TYPE_P2P_GROUP, peer_role_type);
			item->setData(items[1], peer_role_ifname);
			QString details;
			if (items[2] == "GO") {
				details = tr("P2P GO for interface ") +
					items[1];
			} else {
				details = tr("P2P client for interface ") +
					items[1];
			}
			if (text.contains(" [PERSISTENT]"))
				details += "\nPersistent group";
			item->setData(details, peer_role_details);
			item->setToolTip(ItemType(PEER_TYPE_P2P_GROUP));
			model.appendRow(item);
		}
	}

	if (text.startsWith(P2P_EVENT_GROUP_REMOVED)) {
		/* P2P-GROUP-REMOVED wlan0-p2p-0 GO */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;

		if (model.rowCount() == 0)
			return;

		QModelIndexList lst = model.match(model.index(0, 0),
						  peer_role_ifname, items[1]);
		for (int i = 0; i < lst.size(); i++)
			model.removeRow(lst[i].row());
		return;
	}

	if (text.startsWith(P2P_EVENT_PROV_DISC_SHOW_PIN)) {
		/* P2P-PROV-DISC-SHOW-PIN 02:40:61:c2:f3:b7 12345670 */
		QStringList items = text.split(' ');
		if (items.size() < 3)
			return;
		QString addr = items[1];
		QString pin = items[2];

		QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
		if (item == NULL)
			return;
		item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
			      peer_role_selected_method);
		item->setData(pin, peer_role_selected_pin);
		QVariant var = item->data(peer_role_requested_method);
		if (var.isValid() &&
		    var.toInt() == SEL_METHOD_PIN_LOCAL_DISPLAY) {
			ctx_item = item;
			ctx_p2p_display_pin_pd();
		}
		return;
	}

	if (text.startsWith(P2P_EVENT_PROV_DISC_ENTER_PIN)) {
		/* P2P-PROV-DISC-ENTER-PIN 02:40:61:c2:f3:b7 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		QString addr = items[1];

		QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
		if (item == NULL)
			return;
		item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
			      peer_role_selected_method);
		QVariant var = item->data(peer_role_requested_method);
		if (var.isValid() &&
		    var.toInt() == SEL_METHOD_PIN_PEER_DISPLAY) {
			ctx_item = item;
			ctx_p2p_connect();
		}
		return;
	}

	if (text.startsWith(P2P_EVENT_INVITATION_RECEIVED)) {
		/* P2P-INVITATION-RECEIVED sa=02:f0:bc:44:87:62 persistent=4 */
		QStringList items = text.split(' ');
		if (items.size() < 3)
			return;
		if (!items[1].startsWith("sa=") ||
		    !items[2].startsWith("persistent="))
			return;
		QString addr = items[1].mid(3);
		int id = items[2].mid(11).toInt();

		char cmd[100];
		char reply[100];
		size_t reply_len;

		snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", id);
		reply_len = sizeof(reply) - 1;
		if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
			return;
		reply[reply_len] = '\0';
		QString name;
		char *pos = strrchr(reply, '"');
		if (pos && reply[0] == '"') {
			*pos = '\0';
			name = reply + 1;
		} else
			name = reply;

		QStandardItem *item;
		item = find_addr_type(addr, PEER_TYPE_P2P_INVITATION);
		if (item)
			model.removeRow(item->row());

		item = new QStandardItem(*invitation_icon, name);
		if (!item)
			return;
		item->setData(PEER_TYPE_P2P_INVITATION, peer_role_type);
		item->setToolTip(ItemType(PEER_TYPE_P2P_INVITATION));
		item->setData(addr, peer_role_address);
		item->setData(id, peer_role_network_id);

		model.appendRow(item);

		enable_persistent(id);

		return;
	}

	if (text.startsWith(P2P_EVENT_INVITATION_RESULT)) {
		/* P2P-INVITATION-RESULT status=1 */
		/* TODO */
		return;
	}

	if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
		/*
		 * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
		 * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
		 * |Very friendly name|Company|Long description of the model|
		 * WAP|http://w1.fi/|http://w1.fi/hostapd/
		 */
		QStringList items = text.split(' ');
		if (items.size() < 5)
			return;
		QString uuid = items[1];
		QString addr = items[2];
		QString pri_dev_type = items[3].mid(13);
		int wps_state = items[4].mid(10).toInt();

		int pos = text.indexOf('|');
		if (pos < 0)
			return;
		items = text.mid(pos + 1).split('|');
		if (items.size() < 1)
			return;

		QStandardItem *item = find_uuid(uuid);
		if (item)
			return;

		item = new QStandardItem(*ap_icon, items[0]);
		if (item) {
			item->setData(uuid, peer_role_uuid);
			item->setData(addr, peer_role_address);
			int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
				PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
			item->setData(type, peer_role_type);
			item->setToolTip(ItemType(type));
			item->setData(pri_dev_type, peer_role_pri_dev_type);
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			model.appendRow(item);
		}

		return;
	}

	if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
		/* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		if (model.rowCount() == 0)
			return;

		QModelIndexList lst = model.match(model.index(0, 0),
						  peer_role_uuid, items[1]);
		for (int i = 0; i < lst.size(); i++) {
			QStandardItem *item = model.itemFromIndex(lst[i]);
			if (item &&
			    (item->data(peer_role_type).toInt() ==
			     PEER_TYPE_WPS_ER_AP ||
			     item->data(peer_role_type).toInt() ==
			     PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
				model.removeRow(lst[i].row());
		}
		return;
	}

	if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
		/*
		 * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
		 * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
		 * pri_dev_type=1-0050F204-1
		 * |Wireless Client|Company|cmodel|123|12345|
		 */
		QStringList items = text.split(' ');
		if (items.size() < 3)
			return;
		QString uuid = items[1];
		QString addr = items[2];
		QString pri_dev_type = items[6].mid(13);
		int config_methods = -1;
		int dev_passwd_id = -1;

		for (int i = 3; i < items.size(); i++) {
			int pos = items[i].indexOf('=') + 1;
			if (pos < 1)
				continue;
			QString val = items[i].mid(pos);
			if (items[i].startsWith("config_methods=")) {
				config_methods = val.toInt(0, 0);
			} else if (items[i].startsWith("dev_passwd_id=")) {
				dev_passwd_id = val.toInt();
			}
		}

		int pos = text.indexOf('|');
		if (pos < 0)
			return;
		items = text.mid(pos + 1).split('|');
		if (items.size() < 1)
			return;
		QString name = items[0];
		if (name.length() == 0)
			name = addr;

		remove_enrollee_uuid(uuid);

		QStandardItem *item;
		item = new QStandardItem(*laptop_icon, name);
		if (item) {
			item->setData(uuid, peer_role_uuid);
			item->setData(addr, peer_role_address);
			item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
				      peer_role_type);
			item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			item->setData(pri_dev_type, peer_role_pri_dev_type);
			if (config_methods >= 0)
				item->setData(config_methods,
					      peer_role_config_methods);
			if (dev_passwd_id >= 0)
				item->setData(dev_passwd_id,
					      peer_role_dev_passwd_id);
			model.appendRow(item);
		}

		return;
	}

	if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
		/*
		 * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
		 * 02:66:a0:ee:17:27
		 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		remove_enrollee_uuid(items[1]);
		return;
	}

	if (text.startsWith(WPS_EVENT_ENROLLEE_SEEN)) {
		/* TODO: need to time out this somehow or remove on successful
		 * WPS run, etc. */
		/*
		 * WPS-ENROLLEE-SEEN 02:00:00:00:01:00
		 * 572cf82f-c957-5653-9b16-b5cfb298abf1 1-0050F204-1 0x80 4 1
		 * [Wireless Client]
		 * (MAC addr, UUID-E, pri dev type, config methods,
		 * dev passwd id, request type, [dev name])
		 */
		QStringList items = text.split(' ');
		if (items.size() < 7)
			return;
		QString addr = items[1];
		QString uuid = items[2];
		QString pri_dev_type = items[3];
		int config_methods = items[4].toInt(0, 0);
		int dev_passwd_id = items[5].toInt();
		QString name;

		QStandardItem *item = find_addr(addr);
		if (item) {
			int type = item->data(peer_role_type).toInt();
			if (type == PEER_TYPE_ASSOCIATED_STATION)
				return; /* already associated */
		}

		int pos = text.indexOf('[');
		if (pos >= 0) {
			int pos2 = text.lastIndexOf(']');
			if (pos2 >= pos) {
				QStringList items2 =
					text.mid(pos + 1, pos2 - pos - 1).
					split('|');
				name = items2[0];
			}
		}
		if (name.isEmpty())
			name = addr;

		item = find_uuid(uuid);
		if (item) {
			QVariant var = item->data(peer_role_config_methods);
			QVariant var2 = item->data(peer_role_dev_passwd_id);
			if ((var.isValid() && config_methods != var.toInt()) ||
			    (var2.isValid() && dev_passwd_id != var2.toInt()))
				remove_enrollee_uuid(uuid);
			else
				return;
		}

		item = new QStandardItem(*laptop_icon, name);
		if (item) {
			item->setData(uuid, peer_role_uuid);
			item->setData(addr, peer_role_address);
			item->setData(PEER_TYPE_WPS_ENROLLEE,
				      peer_role_type);
			item->setToolTip(ItemType(PEER_TYPE_WPS_ENROLLEE));
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			item->setData(pri_dev_type, peer_role_pri_dev_type);
			item->setData(config_methods,
				      peer_role_config_methods);
			item->setData(dev_passwd_id, peer_role_dev_passwd_id);
			model.appendRow(item);
		}

		return;
	}

	if (text.startsWith(WPA_EVENT_BSS_ADDED)) {
		/* CTRL-EVENT-BSS-ADDED 34 00:11:22:33:44:55 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		char cmd[20];
		snprintf(cmd, sizeof(cmd), "BSS ID-%d", items[1].toInt());
		add_bss(cmd);
		return;
	}

	if (text.startsWith(WPA_EVENT_BSS_REMOVED)) {
		/* CTRL-EVENT-BSS-REMOVED 34 00:11:22:33:44:55 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		remove_bss(items[1].toInt());
		return;
	}
}
Esempio n. 18
0
static RList *r_core_asm_back_disassemble (RCore *core, ut64 addr, int len, ut64 max_hit_count, ut8 disassmble_each_addr, ut32 extra_padding) {
	RList *hits;;
	RCoreAsmHit *found_addr = NULL;
	RAsmOp op;
	ut8 *buf = NULL;
	ut8 max_invalid_b4_exit = 4,
		last_num_invalid = 0;
	int current_instr_len = 0;
	ut64 current_instr_addr = addr,
		current_buf_pos = 0,
		next_buf_pos = len;

	RCoreAsmHit dummy_value;
	ut32 hit_count = 0; 

	if (disassmble_each_addr){
		return r_core_asm_back_disassemble_all(core, addr, len, max_hit_count, extra_padding+1);
	}

	hits = r_core_asm_hit_list_new ();
	buf = malloc (len + extra_padding);

	if (hits == NULL || buf == NULL ){
		if (hits) r_list_destroy (hits);
		if (buf) free (buf); 
		return NULL;
	}

	if (r_io_read_at (core->io, (addr + extra_padding)-len, buf, len+extra_padding) != len+extra_padding) {
		r_list_destroy (hits);
		free (buf);
		return NULL;			
	}

	//
	// XXX - This is a heavy handed approach without a 
	// 		an appropriate btree or hash table for storing
	//	 hits, because are using:
	//			1) Sorted RList with many inserts and searches
	//			2) Pruning hits to find the most optimal disassembly 

	// greedy approach 
	// 1) Consume previous bytes
	// 1a) Instruction is invalid (incr current_instr_addr)
	// 1b) Disasm is perfect 
	// 1c) Disasm is underlap (disasm(current_instr_addr, next_instr_addr - current_instr_addr) short some bytes) 
	// 1d) Disasm is overlap (disasm(current_instr_addr, next_instr_addr - current_instr_addr) over some bytes)

	memset (&dummy_value, 0, sizeof (RCoreAsmHit));
	// disassemble instructions previous to current address, extra_padding can move the location of addr
	// so we need to account for that with current_buf_pos
	current_buf_pos = len - extra_padding - 1;
	next_buf_pos = len + extra_padding - 1;
	current_instr_addr = addr-1;
	do {	
		if (r_cons_singleton ()->breaked) break;
		// reset assembler
		r_asm_set_pc (core->assembler, current_instr_addr);
		current_instr_len = next_buf_pos - current_buf_pos;
		current_instr_len = r_asm_disassemble (core->assembler, &op, buf+current_buf_pos, current_instr_len);
		found_addr = find_addr(hits, current_instr_addr);

		IFDBG {
			ut32 byte_cnt =  current_instr_len ? current_instr_len : 1;
			eprintf("current_instr_addr: 0x%"PFMT64x", current_buf_pos: 0x%"PFMT64x", current_instr_len: %d \n", current_instr_addr, current_buf_pos, current_instr_len);

			ut8 *hex_str = (ut8*)r_hex_bin2strdup(buf+current_buf_pos, byte_cnt);
			eprintf("==== current_instr_bytes: %s ",hex_str);

			if (current_instr_len > 0) 
				eprintf("op.buf_asm: %s\n", op.buf_asm);
			else
				eprintf("op.buf_asm: <invalid>\n");

			if (hex_str) free(hex_str);
		}

		// disassembly invalid
		if (current_instr_len == 0 || strstr (op.buf_asm, "invalid")) {
			if (current_instr_len == 0) current_instr_len = 1;
			add_hit_to_sorted_hits(hits, current_instr_addr, current_instr_len, /* is_valid */ R_FALSE);
			hit_count ++;
			last_num_invalid ++;
		// disassembly perfect
		} else if (current_buf_pos + current_instr_len == next_buf_pos) {
            // i think this may be the only case where an invalid instruction will be
            // added because handle_forward_disassemble and handle_disassembly_overlap
            // are only called in cases where a valid instruction has been found.
            // and they are lazy, since they purge the hit list 
            ut32 purge_results = 0;
			ut8 is_valid = R_TRUE;
			IFDBG eprintf(" handling underlap case: current_instr_addr: 0x%"PFMT64x".\n", current_instr_addr);
			purge_results =  prune_hits_in_addr_range(hits, current_instr_addr, current_instr_len, /* is_valid */ R_TRUE);
			if (purge_results) {
				handle_forward_disassemble(core, hits, buf, len, current_buf_pos+current_instr_len, current_instr_addr+current_instr_len, addr);
				hit_count = r_list_length(hits);
			}
			add_hit_to_sorted_hits(hits, current_instr_addr, current_instr_len, is_valid);
			//handle_forward_disassemble(core, hits, buf, len, current_buf_pos+current_instr_len, current_instr_addr+current_instr_len, addr/*end_addr*/);
			hit_count ++;	
			next_buf_pos = current_buf_pos;  
			last_num_invalid = 0;
		// disassembly underlap
		} else if (current_buf_pos + current_instr_len < next_buf_pos) {
			ut32 purge_results = 0;
			ut8 is_valid = R_TRUE;
			purge_results =  prune_hits_in_addr_range(hits, current_instr_addr, current_instr_len, /* is_valid */ R_TRUE);
			add_hit_to_sorted_hits(hits, current_instr_addr, current_instr_len, is_valid);

			if (hit_count < purge_results ) hit_count = 0; // WTF??
			else hit_count -= purge_results;

			next_buf_pos = current_buf_pos;
			handle_forward_disassemble(core, hits, buf, len - extra_padding, current_buf_pos+current_instr_len, current_instr_addr+current_instr_len, addr);
			hit_count = r_list_length(hits);
			last_num_invalid = 0;
		// disassembly overlap
		} else if (current_buf_pos + current_instr_len > next_buf_pos) {
			//ut64 value = handle_disassembly_overlap(core, hits, buf, len, current_buf_pos, current_instr_addr);
			next_buf_pos = current_buf_pos;
			hit_count = r_list_length (hits);
			last_num_invalid = 0;
		}

		// walk backwards by one instruction
		IFDBG eprintf(" current_instr_addr: 0x%"PFMT64x" current_instr_len: %d next_instr_addr: 0x%04llx \n",
			current_instr_addr, current_instr_len, next_buf_pos);
		IFDBG eprintf(" hit count: %d \n", hit_count );
		current_instr_addr -= 1;
		current_buf_pos -= 1;

		if ( hit_count >= max_hit_count && 
			 (last_num_invalid >= max_invalid_b4_exit || last_num_invalid == 0))  
			break;
	} while ( ((int) current_buf_pos  >= 0) && (int)(len - current_buf_pos) >= 0 );

	r_asm_set_pc (core->assembler, addr);
	if (buf) free (buf);
	return hits;
}