Exemplo n.º 1
0
LIB_EXPORT plc_tag plc_tag_create(const char *attrib_str)
{
	plc_tag tag = PLC_TAG_NULL;
	attr attribs = NULL;
	int rc = PLCTAG_STATUS_OK;

	if(!attrib_str || !str_length(attrib_str)) {
		return PLC_TAG_NULL;
	}

	attribs = attr_create_from_str(attrib_str);

	if(!attribs) {
		return PLC_TAG_NULL;
	}

	/*
	 * create the tag, this is protocol specific.
	 *
	 * If this routine wants to keep the attributes around, it needs
	 * to clone them.
	 */
	tag = ab_tag_create(attribs);

	/*
	 * FIXME - this really should be here???  Maybe not?  But, this is
	 * the only place it can be without making every protocol type do this automatically.
	 */
	if(tag && tag->status == PLCTAG_STATUS_OK) {
		rc = mutex_create(&tag->mut);

		tag->status = rc;

		tag->read_cache_expire = (uint64_t)0;
		tag->read_cache_ms = attr_get_int(attribs,"read_cache_ms",0);
	}

	/*
	 * Release memory for attributes
	 *
	 * some code is commented out that would have kept a pointer
	 * to the attributes in the tag and released the memory upon
	 * tag destruction. To prevent a memory leak without maintaining
	 * that pointer, the memory needs to be released here.
	 */
	attr_destroy(attribs);

	return tag;
}
Exemplo n.º 2
0
plc_tag ab_tag_create(attr attribs)
{
    ab_tag_p tag = AB_TAG_NULL;
    const char *path;
	int rc;
	int debug = attr_get_int(attribs,"debug",0);

    pdebug(debug,"Starting.");


    /*
     * allocate memory for the new tag.  Do this first so that
     * we have a vehicle for returning status.
     */

    tag = (ab_tag_p)mem_alloc(sizeof(struct ab_tag_t));

    if(!tag) {
    	pdebug(debug,"Unable to allocate memory for AB EIP tag!");
    	return PLC_TAG_NULL;
    }

    /* store the debug status */
    tag->debug = debug;

    /*
     * check the CPU type.
     *
     * This determines the protocol type.
     */
    if(check_cpu(tag, attribs) != PLCTAG_STATUS_OK) {
        tag->status = PLCTAG_ERR_BAD_DEVICE;
        return (plc_tag)tag;
    }

    /* AB PLCs are little endian. */
    tag->endian = PLCTAG_DATA_LITTLE_ENDIAN;

    /* allocate memory for the data */
    tag->elem_count = attr_get_int(attribs,"elem_count",1);
    tag->elem_size = attr_get_int(attribs,"elem_size",0);
    tag->size = (tag->elem_count) * (tag->elem_size);

    if(tag->size == 0) {
    	/* failure! Need data_size! */
    	tag->status = PLCTAG_ERR_BAD_PARAM;
    	return (plc_tag)tag;
    }

    tag->data = (uint8_t*)mem_alloc(tag->size);

    if(tag->data == NULL) {
    	tag->status = PLCTAG_ERR_NO_MEM;
    	return (plc_tag)tag;
    }

    /* get the connection path, punt if there is not one and we have a Logix-class PLC. */
    path = attr_get_str(attribs,"path",NULL);

    if(path == NULL && tag->protocol_type == AB_PROTOCOL_LGX) {
    	tag->status = PLCTAG_ERR_BAD_PARAM;
    	return (plc_tag)tag;
    }

    /* make sure the global mutex is set up */
    rc = check_mutex(tag->debug);
    if(rc != PLCTAG_STATUS_OK) {
    	tag->status = rc;
    	return (plc_tag)tag;
    }

    tag->first_read = 1;

	/*
	 * now we start the part that might conflict with other threads.
	 *
	 * The rest of this is inside a locked block.
	 */
	pdebug(debug,"Locking mutex");
	critical_block(io_thread_mutex) {
		/*
		 * set up tag vtable.  This is protocol specific
		 */
		tag->vtable = set_tag_vtable(tag);

		if(!tag->vtable) {
			pdebug(debug,"Unable to set tag vtable!");
			tag->status = PLCTAG_ERR_BAD_PARAM;
			break;
		}

		/*
		 * Check the request IO handler thread.
		 */
		if(!io_handler_thread) {
			rc = thread_create((thread_p*)&io_handler_thread,request_handler_func, 32*1024, NULL);
			if(rc != PLCTAG_STATUS_OK) {
				pdebug(debug,"Unable to create request handler thread!");
				tag->status = rc;
				break;
			}
		}

		/*
		 * Find or create a session.
		 */
		if(find_or_create_session(tag, attribs) != PLCTAG_STATUS_OK) {
			pdebug(debug,"Unable to create session!");
			tag->status = PLCTAG_ERR_BAD_GATEWAY;
			break;
		}

		/*
		 * parse the link path into the tag.  Note that it must
		 * pad the byte string to a multiple of 16-bit words. The function
		 * also adds the protocol/PLC specific routing information to the
		 * links specified.  This fills in fields in the connection about
		 * any DH+ special data.
		 * 
		 * Skip this if we don't have a path.
		 */
		if(path && cip_encode_path(tag,path) != PLCTAG_STATUS_OK) {
			pdebug(debug,"Unable to convert links strings to binary path!");
			tag->status = PLCTAG_ERR_BAD_PARAM;
			break;
		}


		/*
		 * check the tag name, this is protocol specific.
		 */

		if(check_tag_name(tag, attr_get_str(attribs,"name","NONE")) != PLCTAG_STATUS_OK) {
			pdebug(debug,"Bad tag name!");
			tag->status = PLCTAG_ERR_BAD_PARAM;
			break;
		}

		/*
		 * add the tag to the session's list.
		 */
		if(session_add_tag_unsafe(tag, tag->session) != PLCTAG_STATUS_OK) {
			pdebug(debug,"unable to add new tag to connection!");

			tag->status = PLCTAG_ERR_CREATE;
			break;
		}
    }

    pdebug(debug,"Done.");

    return (plc_tag)tag;
}
Exemplo n.º 3
0
static void ctrl_inject(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *bssid, *sta_addr;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	int frame, sender_ap, prot;
	int ret = 0;

	bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
	sta_addr = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_STA_ADDR);
	frame = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_FRAME);
	sender_ap = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_SENDER_AP);
	if (sender_ap < 0)
		sender_ap = 0;
	prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
	if (bssid == NULL || sta_addr == NULL || frame < 0 || prot < 0) {
		wpa_printf(MSG_INFO, "Invalid inject command parameters");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	bss = bss_find(wt, bssid);
	if (bss == NULL) {
		wpa_printf(MSG_INFO, "BSS not found for inject command");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	if (is_broadcast_ether_addr(sta_addr)) {
		if (!sender_ap) {
			wpa_printf(MSG_INFO, "Invalid broadcast inject "
				   "command without sender_ap set");
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
			return;
		} sta = NULL;
	} else {
		sta = sta_find(bss, sta_addr);
		if (sta == NULL) {
			wpa_printf(MSG_INFO, "Station not found for inject "
				   "command");
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
			return;
		}
	}

	switch (frame) {
	case WLANTEST_FRAME_AUTH:
		ret = ctrl_inject_auth(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_ASSOCREQ:
		ret = ctrl_inject_assocreq(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_REASSOCREQ:
		ret = ctrl_inject_reassocreq(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_DEAUTH:
		ret = ctrl_inject_deauth(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_DISASSOC:
		ret = ctrl_inject_disassoc(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_SAQUERYREQ:
		ret = ctrl_inject_saqueryreq(wt, bss, sta, sender_ap, prot);
		break;
	default:
		wpa_printf(MSG_INFO, "Unsupported inject command frame %d",
			   frame);
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	if (ret)
		wpa_printf(MSG_INFO, "Failed to inject frame");
	else
		wpa_printf(MSG_INFO, "Frame injected successfully");
	ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
			 WLANTEST_CTRL_FAILURE);
}
Exemplo n.º 4
0
static void ctrl_send_(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u8 *bssid, *sta_addr;
	int prot;
	u8 *frame;
	size_t frame_len;
	int ret = 0;
	struct ieee80211_hdr *hdr;
	u16 fc;

	frame = attr_get(cmd, clen, WLANTEST_ATTR_FRAME, &frame_len);
	prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
	if (frame == NULL || frame_len < 24 || prot < 0) {
		wpa_printf(MSG_INFO, "Invalid send command parameters");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	hdr = (struct ieee80211_hdr *) frame;
	fc = le_to_host16(hdr->frame_control);
	switch (WLAN_FC_GET_TYPE(fc)) {
	case WLAN_FC_TYPE_MGMT:
		bssid = hdr->addr3;
		if (os_memcmp(hdr->addr2, hdr->addr3, ETH_ALEN) == 0)
			sta_addr = hdr->addr1;
		else
			sta_addr = hdr->addr2;
		break;
	case WLAN_FC_TYPE_DATA:
		switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
		case 0:
			bssid = hdr->addr3;
			sta_addr = hdr->addr2;
			break;
		case WLAN_FC_TODS:
			bssid = hdr->addr1;
			sta_addr = hdr->addr2;
			break;
		case WLAN_FC_FROMDS:
			bssid = hdr->addr2;
			sta_addr = hdr->addr1;
			break;
		default:
			wpa_printf(MSG_INFO, "Unsupported inject frame");
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
			return;
		}
		break;
	default:
		wpa_printf(MSG_INFO, "Unsupported inject frame");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	bss = bss_find(wt, bssid);
	if (bss == NULL) {
		wpa_printf(MSG_INFO, "Unknown BSSID");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	sta = sta_find(bss, sta_addr);
	if (sta == NULL) {
		wpa_printf(MSG_INFO, "Unknown STA address");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	ret = wlantest_inject(wt, bss, sta, frame, frame_len, prot);

	if (ret)
		wpa_printf(MSG_INFO, "Failed to inject frame");
	else
		wpa_printf(MSG_INFO, "Frame injected successfully");
	ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
			 WLANTEST_CTRL_FAILURE);
}