/// Report an error if address isn't a numerical IPv4 address.
    bool checkValidAddress(const std::string& address) {
        if (IPv4Addr::isProperAddress(address)) return true;
        else ND_ERROR("[%s] Invalid IP address provided (%s); must be numerical IPv4 or IPv6 format.\n",
                          getName().c_str(), address.c_str());

        return false;
    }
 /// Report an error if port isn't between 0 and 65535.
 bool checkValidPort(const int& port) {
     if ( port < 0 || port > 65535 ) {
         ND_ERROR("[%s] Invalid port provided (%d); must be between 0 and 65535.\n",
                  getName().c_str(), port);
         return false;
     }
     return true;
 }
Exemple #3
0
/* allocate one page of cached, shared (dma-able) or regular memory */
NDIS_STATUS
shared_allocpage(
	IN shared_info_t *shared,
	IN BOOLEAN shared_mem,
	IN BOOLEAN cached,
	OUT page_t *page
)
{
	NDIS_STATUS status;

	/* uncached not supported */
	ASSERT(cached);

	bzero(page, sizeof(page_t));
	if (shared_mem) {
			NdisMAllocateSharedMemory(shared->adapterhandle, PAGE_SIZE, cached,
			                          (void **) &page->va, &page->pa);

		/* Make sure that we got valid address */
		if (!osl_dmaddr_valid(shared->osh, page->pa.LowPart, page->pa.HighPart)) {
			ND_ERROR(("%s%d: shared_allocpage: pa not valid \n", shared->id,
			          shared->unit));
			NdisMFreeSharedMemory(shared->adapterhandle, PAGE_SIZE,
			                      cached, (PVOID)page->va, page->pa);
			return (NDIS_STATUS_RESOURCES);
		}
	} else
		page->va = MALLOC(shared->osh, PAGE_SIZE);
	if (page->va == NULL) {
		ND_ERROR(("%s%d: shared_allocpage: out of memory, malloced %d bytes\n", shared->id,
		          shared->unit, MALLOCED(shared->osh)));
		return (NDIS_STATUS_RESOURCES);
	}
	ASSERT(!shared_mem || ISALIGNED((uintptr)page->va, PAGE_SIZE));
	ASSERT(page->pa.HighPart == 0);
	ASSERT(ISALIGNED(page->pa.LowPart, PAGE_SIZE));
	status = NDIS_STATUS_SUCCESS;

	return (status);
}
unsigned EthernetFrame::setBack(ACE_UINT8* buffer, const unsigned bufLen) {
	ACE_TRACE("EthernetFrame::setBack");
	throwIfUninitialized(); // setHeader() has to be called first

	if ( getExpectedLength() != bufLen + minBytesToDetermineLength() ) {
		ND_ERROR("Expected length %d != %d + buffer size %d (type is %04X)!\n",
			getExpectedLength(), minBytesToDetermineLength(), bufLen, getEtherType());
		throw std::runtime_error("Expected Ethernet header/payload length is different than buffer.");
	}
	
	setBufferSize(getExpectedLength());
	copyUnit(ptrUnit() + minBytesToDetermineLength(), buffer, bufLen);

	return getUnitLength();
}
devEthernet::devEthernet(const std::string& newName /* = "" */,
	const CE_DLL* newDLLPtr /* = 0 */):
	CE_Device(newName, newDLLPtr),
	_ifaceName(""),
	_ifaceNameSetting(CEcfg::instance()->getOrAddString(cfgKey("ifaceName"), _ifaceName)),
	_vendor(""),
	_model(""),
	_packetSocket(ACE_INVALID_HANDLE),
	_netlinkSocket(0),
	_snapLen(CEcfg::instance()->getOrAddInt(cfgKey("snapLen"), 0)),
	_activateOnLoad(CEcfg::instance()->getOrAddBool(cfgKey("activateOnLoad"), true)),
	_noArpSetting(CEcfg::instance()->getOrAddBool(cfgKey("flagNoARP"), false)),
	_promiscSetting(CEcfg::instance()->getOrAddBool(cfgKey("flagPromisc"), false))
	{

	CEcfg::instance()->getOrAddString(cfgKey("devType")) = "Ethernet";

	if ( strcmp(_ifaceNameSetting.c_str(), "") == 0) {
		MOD_INFO("Getting interface name from Device name (%s).", newName.c_str());
		setIfaceName(newName);
	}
	else {
		MOD_INFO("Getting interface name from config file (%s).", _ifaceNameSetting.c_str());
		_ifaceName = static_cast<const char*>(_ifaceNameSetting);
	}

	if ( ! _ifaceName.empty() ) {
		if ( isProtected() )
			throw IsProtected("Device " + getIfaceName() + " is marked 'protected' and cannot be managed by the CE.");

		// IOCtlFailed is thrown if there's an error
		try {
			_ioctl(SIOCGIFFLAGS, _savedFlags, "Error getting flags for interface " + getIfaceName()
				+ " via SIOCGIFFLAGS: ");
		}
		catch (...) {
			MOD_ERROR("Could not read flags to restore later.");
		}

		try {
			if (getActivateOnLoad()) activate();
		}
		catch (...) {
			MOD_ERROR("Unable to activate at this time.");
		}

		if ( CEcfg::instance()->exists(cfgKey("MTU")) )
			setMTU(static_cast<unsigned int>(CEcfg::instance()->get(cfgKey("MTU"))));
	}

	if ( getSnapLen() == 0 ) {
		MOD_DEBUG("Automatically setting snapLen.");
		setSnapLen(static_cast<int>(getMTU() + 30));
		MOD_DEBUG("SnapLen set to %d.", getSnapLen());
	}

	MOD_DEBUG("Connecting netlink socket.");
	_netlinkSocket = Linux::nl_socket_alloc();

 	if (Linux::nl_connect(_netlinkSocket, NETLINK_ROUTE) < 0) {
 		ND_ERROR("[%s] Unable to connect netlink socket: %s\n", nl_geterror(errno));
 		Linux::nl_socket_free(_netlinkSocket);
 	}

 	MOD_DEBUG("Ethernet constructor complete.");
}
Exemple #6
0
NDIS_STATUS
shared_lb_alloc(
	IN shared_info_t *shared,
	IN struct lbfree *l,
	IN uint total,
	IN BOOLEAN shared_mem,
	IN BOOLEAN cached,
	IN BOOLEAN piomode,
	IN BOOLEAN data_buf
)
{
	NDIS_STATUS status;
	page_t page;
	int maxpages;
	int i;
	uint ipp, lbdatasz;

	/* uncached not supported */
	ASSERT(cached);

	if (data_buf)
		total = ROUNDUP(total, BPP);
	else
		/* add one if LBPP is not page aligned */
		total = ROUNDUP(total, (LBPP + ((PAGE_SIZE % sizeof(struct lbuf)) ? 1 : 0)));

	ND_TRACE(("%s%d: shared_lb_alloc: total %d\n", shared->id, shared->unit, total));

	l->free = NULL;
	l->total = total;
	l->count = 0;
	l->size = data_buf ? LBUFSZ : sizeof(struct lbuf);
	l->pages = NULL;
	l->npages = 0;
	l->headroom = 0;
	NdisAllocateSpinLock(&l->queue_lock);

	maxpages = (l->total * l->size) / PAGE_SIZE;

	/* allocate page list memory */
	if ((l->pages = (page_t*) MALLOC(shared->osh, maxpages * sizeof(page_t))) == NULL)
		goto enomem;
	bzero(l->pages, maxpages * sizeof(page_t));

	/* set item per page number and data size */
	if (data_buf) {
		ipp = BPP;
		lbdatasz = LBDATASZ;
	} else {
		ipp = LBPP;
		lbdatasz = 0;
	}

	/* fill the freelist */
	for (i = 0; i < maxpages; i++) {
		status = shared_allocpage(shared, shared_mem, cached, &page);
		if (NDIS_ERROR(status))
			goto enomem;
		status = shared_lb_addpage(shared, l, piomode, &page, ipp, lbdatasz);
		if (NDIS_ERROR(status))
			goto enomem;
	}

	return (NDIS_STATUS_SUCCESS);

enomem:
	ND_ERROR(("%s%d: shared_lb_alloc: out of memory, malloced %d bytes\n", shared->id,
	          shared->unit, MALLOCED(shared->osh)));
	shared_lb_free(shared, l, shared_mem, TRUE);
	return (NDIS_STATUS_RESOURCES);
}
Exemple #7
0
NDIS_STATUS
shared_flush(
	IN shared_info_t *shared,
	IN uchar *va,
	IN ULONG pa,
	IN ULONG len,
	IN BOOLEAN writetodevice
)
{
#ifndef NDIS60
	PNDIS_BUFFER b;
	NDIS_STATUS status;
	NDIS_PHYSICAL_ADDRESS npa;

	/* if receive, buffer must begin and end on a cacheline boundary */
	if (!writetodevice) {
		ASSERT(ISALIGNED((uintptr)va, shared->cacheline));
		len = ROUNDUP(len, shared->cacheline);
	}

	/* alloc a temp buffer descriptor */
	NdisAllocateBuffer(&status, &b, shared->rxbufferpool, va, len);
	if (status != NDIS_STATUS_SUCCESS) {
		ND_ERROR(("%s%d: shared_flush: NdisAllocateBuffer error 0x%x\n",
			shared->id, shared->unit, status));
		return status;
	}

	/* flush processor cache */
	NdisAdjustBufferLength(b, len);
	NdisFlushBuffer(b, writetodevice);

	npa.HighPart = 0;
	npa.LowPart = pa;

#ifndef USEWDK


	if (!writetodevice)
		NdisMUpdateSharedMemory(shared->adapterhandle, len, va, npa);

#endif /* USEWDK */

	/* free the temp buffer descriptor */
	NdisFreeBuffer(b);
#else /* NDIS60 */
	PMDL b;

	/* if receive, buffer must begin and end on a cacheline boundary */
	if (!writetodevice) {
		ASSERT(ISALIGNED((uintptr)va, shared->cacheline));
		len = ROUNDUP(len, shared->cacheline);
	}

	/* alloc a temp MDL */
	b = NdisAllocateMdl(shared->adapterhandle, va, len);
	if (b == NULL) {
		ND_ERROR(("%s%d: shared_flush: NdisAllocateMdl error\n", shared->id, shared->unit));
		return NDIS_STATUS_FAILURE;
	}

	/* flush processor cache */
	NdisAdjustMdlLength(b, len);
	NdisFlushBuffer(b, writetodevice);

	/* free the temp MDL */
	NdisFreeMdl(b);
#endif /* NDIS60 */
	return NDIS_STATUS_SUCCESS;
}