예제 #1
0
파일: arp.c 프로젝트: dan-sw/DAN-uMon
/* SendArpRequest():
 */
int
SendArpRequest(uchar *ip)
{
    struct arphdr *ta;
    struct ether_header *te;
    unsigned long arppkt[ARPSIZE/2];

    /* Populate the ethernet header: */
    te = (struct ether_header *) arppkt;
    memcpy((char *)&(te->ether_shost), (char *)thismac.ether_addr_octet,6);
    memcpy((char *)&(te->ether_dhost), (char *)BroadcastAddr,6);
    te->ether_type = ecs(ETHERTYPE_ARP);

    /* Populate the arp header: */
    ta = (struct arphdr *) (te + 1);
    ta->hardware = ecs(1);		/* 1 for ethernet */
    ta->protocol = ecs(ETHERTYPE_IP);
    ta->hlen = 6;		/* Length of hdware (ethernet) address */
    ta->plen = 4;		/* Length of protocol (ip) address */
    ta->operation = ecs(ARP_REQUEST);
    memcpy((char *)ta->senderha, (char *)thismac.ether_addr_octet,6);
    memcpy((char *)ta->senderia, (char *)&thisip.s_addr,4);
    memcpy((char *)ta->targetha, (char *)BroadcastAddr,6);
    memcpy((char *)ta->targetia, (char *)ip,4);
    mon_sendenetpkt((char *)arppkt,ARPSIZE);
    return(0);
}
예제 #2
0
void CPostableObject::DetachThread()
{
	if (!m_dwThreadId)
		return;

	// Get current thread info
	POSTABLETHREADINFO* pti=GetThreadInfo(m_dwThreadId, false);
	ASSERT(pti!=NULL);

	{
		// Remove any messages for this object from the queue
		CEnterCriticalSection ecs(&pti->m_Section);
		if (m_iQueuedMessages)
		{
			for (int i=pti->m_MessageQueue.GetSize()-1; i>=0; i--)
			{
				// Message for this object?
				if (pti->m_MessageQueue[i]->pTarget==this)
				{
					// Mark as an obsolete message
					pti->m_MessageQueue[i]->pTarget=NULL;
				}
			}
		}

		pti->m_dwCount--;
		if (pti->m_dwCount==0)
		{
			PostMessage(pti->m_hWndDispatcher, WM_POSTABLE_CLOSE, 0, 0);
		}
	}

	m_iQueuedMessages=0;
	m_dwThreadId=0;
}
예제 #3
0
파일: arp.c 프로젝트: dan-sw/DAN-uMon
/* SendArpResp():
 *	Called in response to an ARP REQUEST.  The incoming ethernet
 *	header pointer points to the memory area that contains the incoming
 *	ethernet packet that this function is called in response to.
 *	In other words, it is used to fill the majority of the response
 *	packet fields.
 */
int
SendArpResp(struct ether_header *re)
{
    struct arphdr *ta, *ra;
    struct ether_header *te;
    unsigned long arppkt[ARPSIZE/2];

    te = (struct ether_header *) arppkt;
    memcpy((char *)&(te->ether_shost), (char *)thismac.ether_addr_octet,6);
    memcpy((char *)&(te->ether_dhost),(char *)&(re->ether_shost),6);
    te->ether_type = ecs(ETHERTYPE_ARP);

    ta = (struct arphdr *) (te + 1);
    ra = (struct arphdr *) (re + 1);
    ta->hardware = ra->hardware;
    ta->protocol = ra->protocol;
    ta->hlen = ra->hlen;
    ta->plen = ra->plen;
    ta->operation = ARP_RESPONSE;
    memcpy((char *)ta->senderha, (char *)thismac.ether_addr_octet,6);
    memcpy((char *)ta->senderia, (char *)ra->targetia,4);
    memcpy((char *)ta->targetha, (char *)ra->senderha,6);
    memcpy((char *)ta->targetia, (char *)ra->senderia,4);
    self_ecs(ta->hardware);
    self_ecs(ta->protocol);
    self_ecs(ta->operation);
    mon_sendenetpkt((char *)arppkt,ARPSIZE);
    return(0);
}
예제 #4
0
LRESULT CPostableObject::PostAndWait(UINT nMessage, WPARAM wParam, LPARAM lParam)
{
	ASSERT(m_dwThreadId!=0);

	// Get thread info
	POSTABLETHREADINFO* pti=GetThreadInfo(m_dwThreadId, false);
	ASSERT(pti!=NULL);

	// Setup for response...
	CEvent hReplyEvent(true);
	LRESULT lResult=0;

	// Setup a new message
	POSTABLEMESSAGE* p=new POSTABLEMESSAGE;
	p->pTarget=this;
	p->nMessage=nMessage;
	p->wParam=wParam;
	p->lParam=lParam;
	p->hReplyEvent=hReplyEvent;
	p->pResult=&lResult;

	{
		CEnterCriticalSection ecs(&pti->m_Section);

		m_iQueuedMessages++;
		pti->m_MessageQueue.Add(p);

		// If no pending Windows message, post one...
		if (!pti->m_bPostPending)
		{
			// Unless we're currently dispatching messages... in which case we'll post at the end of that.
			if (!pti->m_bDispatching)
			{
				PostMessage(pti->m_hWndDispatcher, WM_POSTABLE_DISPATCH, 0, 0);
			}

			// Set flag saying post is pending
			pti->m_bPostPending=true;
		}
	}

	while (true)
	{
		// Dispatch messages...
		MSG msg;
		while (PeekMessage(&msg, 0, 0, NULL, PM_REMOVE))
		{
			if (!IsInputMessage(msg.message))
			{
				DispatchMessage(&msg);
			}
		}

		// Wait for response...
		if (MsgWaitForMultipleObjects(1, &hReplyEvent.m_hObject, FALSE, INFINITE, QS_ALLEVENTS)==WAIT_OBJECT_0)
			return lResult;
	}
}
예제 #5
0
// Helper to retrieve info about a thread...
static POSTABLETHREADINFO* GetThreadInfo(DWORD dwThread, bool bCreate)
{
	CEnterCriticalSection ecs(&g_Section);

	POSTABLETHREADINFO* pti=g_ThreadInfos.Get(dwThread, NULL);
	if (pti || !bCreate)
		return pti;

	pti=new POSTABLETHREADINFO();
	g_ThreadInfos.Add(dwThread, pti);
	return pti;
}
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Pop
 *  Description:  以互斥的方式从队列中取出一条消息
 * =====================================================================================
 */
CMessage * CUsrDefMsgQueue::Pop()
{
	CEnterCriticalSection ecs(&m_Mutex);
 	if( IsEmpty() )
 	{
 		return 0;
 	}
		
	CMessage * pMsg = m_pQueueSpace[m_iQueueHead];
 	m_iQueueHead = (m_iQueueHead + 1) % m_iTotalRoom;
	return pMsg;
}
예제 #7
0
	void Dispatch()
	{
		CEnterCriticalSection ecs(&m_Section);

		// This should never go reentrant
		ASSERT(!m_bDispatching);

		// Clear flag
		m_bPostPending=false;

		// Dispatch all pending messages...
		m_bDispatching=true;
		int iCount=m_MessageQueue.GetSize();
		for (int i=0; i<iCount; i++)	
		{
			POSTABLEMESSAGE* p=m_MessageQueue[i];
			if (p->pTarget!=NULL)
			{
				// Update queued message count
				p->pTarget->m_iQueuedMessages--;

				// Release lock while we send it
				ecs.Leave();

				// Dispatch the message
				ASSERT(p->pTarget->GetThreadId()==GetCurrentThreadId());
				LRESULT lResult=p->pTarget->OnMessage(p->nMessage, p->wParam, p->lParam);
				if (p->hReplyEvent)
				{
					*p->pResult=lResult;
					SetEvent(p->hReplyEvent);
				}

				// Reclaim lock
				ecs.Enter(&m_Section);
			}
		}
		m_bDispatching=false;

		// Remove messages just dispatched...
		m_MessageQueue.RemoveAt(0, iCount);

		// If messages got posted while dispatching messages, post the Windows message now...
		if (m_MessageQueue.GetSize()>0)
		{
			ASSERT(m_bPostPending);
			PostMessage(m_hWndDispatcher, WM_POSTABLE_DISPATCH, 0, 0);
		}
	}
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Push
 *  Description:  以互斥的方式向消息队列中插入一条消息
 * =====================================================================================
 */
CStatus CUsrDefMsgQueue::Push(CMessage * pMsg)
{
	CEnterCriticalSection ecs(&m_Mutex);	
	if( IsFull() )
	{
		CStatus s = EnlargeQueue();
		if(!s.IsSuccess())
			return CStatus(-1,0,"failed to Enlarge the queue!");
	}

	m_pQueueSpace[m_iQueueTail] = pMsg;
	m_iQueueTail = (m_iQueueTail + 1) % m_iTotalRoom;

	return CStatus(0,0);
}
예제 #9
0
void CPostableObject::AttachThread()
{
	// Save the current thread ID
	m_dwThreadId=GetCurrentThreadId();
	m_iQueuedMessages=0;

	CEnterCriticalSection ecs1(&g_Section);

	// Get info for this thread, creating it if need be
	POSTABLETHREADINFO* pti=GetThreadInfo(m_dwThreadId, true);
	ASSERT(pti!=NULL);

	// Bump the count...
	CEnterCriticalSection ecs(&pti->m_Section);
	pti->m_dwCount++;
}
예제 #10
0
// Post a message to this object
void CPostableObject::Post(UINT nMessage, WPARAM wParam, LPARAM lParam)
{
	ASSERT(m_dwThreadId!=0);

	// Get thread info
	POSTABLETHREADINFO* pti=GetThreadInfo(m_dwThreadId, false);
	ASSERT(pti!=NULL);

	// Setup a new message
	POSTABLEMESSAGE* p=new POSTABLEMESSAGE;
	p->pTarget=this;
	p->nMessage=nMessage;
	p->wParam=wParam;
	p->lParam=lParam;
	p->hReplyEvent=NULL;
	p->pResult=NULL;

	{
		CEnterCriticalSection ecs(&pti->m_Section);

		pti->m_MessageQueue.Add(p);
		m_iQueuedMessages++;

		// If no pending Windows message, post one...
		if (!pti->m_bPostPending)
		{
			// Unless we're currently dispatching messages... in which case we'll post at the end of that.
			if (!pti->m_bDispatching)
			{
				PostMessage(pti->m_hWndDispatcher, WM_POSTABLE_DISPATCH, 0, 0);
			}

			// Set flag saying post is pending
			pti->m_bPostPending=true;
		}
	}
}
예제 #11
0
파일: arp.c 프로젝트: dan-sw/DAN-uMon
uchar *
ArpEther(struct udpinfo *u, uchar *ecpy)
{
    struct 	ether_header *ehdr;
    uchar	*binip, *gbinip, *Ip, *ep;
    int		size, retry, timeoutsecs;

    binip = (uchar *)&u->dip.s_addr;
    gbinip = (uchar *)&thisgip.s_addr;

    /* First check local cache. If found, return with pointer to MAC. */
    ep = EtherFromCache(binip);
    if (ep) {
        if (ecpy) {
            memcpy((char *)ecpy, (char *)ep,6);
            ep = ecpy;
        }
        return(ep);
    }

    retry = 0;
    while(1) {
        /* If IP is not on this net, the get the GATEWAY IP address.
         */
        if (!IpIsOnThisNet(binip)) {
            ep = EtherFromCache(gbinip);
            if (ep) {
                if (ecpy) {
                    memcpy((char *)ecpy, (char *)ep,6);
                    ep = ecpy;
                }
                return(ep);
            }
            SendArpRequest(gbinip);
            Ip = gbinip;
        }
        else {
            SendArpRequest(binip);
            Ip = binip;
        }

        /* Now that the request has been issued, wait for a while to see if
         * the ARP cache is loaded with the result of the request.
         */
        for(timeoutsecs=0; timeoutsecs<1000000; timeoutsecs++) {
            ep = EtherFromCache(Ip);
            if (ep)
                break;
            size = mon_recvenetpkt(u->packet,u->plen);
            if (size == 0)
                continue;
            ehdr = (struct ether_header *)u->packet;
            if (!memcmp(ehdr->ether_shost.ether_addr_octet,
                        thismac.ether_addr_octet,6)) {
                continue;
            }
            if (ehdr->ether_type == ecs(ETHERTYPE_ARP)) {
                processARP(ehdr,size);
            }
        }
        if (ep) {
            if (ecpy) {
                memcpy((char *)ecpy, (char *)ep,6);
                ep = ecpy;
            }
            return(ep);
        }
        retry++;
    }
    return(0);
}
예제 #12
0
int
sendSyslog(uchar *syslogsrvr,char *msg, short port, int null)
{
	int	msglen;
	uchar *syslogmsg;
	ushort ip_len, sport;
	struct ether_header *enetp;
	struct ip *ipp;
	struct Udphdr *udpp;
	uchar	binip[8], binenet[8], *enetaddr;

	/* msglen is the length of the message, plus optionally the 
	 * terminating null character (-n option of syslog command)..
	 */
	msglen = strlen(msg) + null;

	/* Convert IP address to binary:
	 */
	if (IpToBin((char *)syslogsrvr,(unsigned char *)binip) < 0)
		return(0);

	/* Get the ethernet address for the IP:
	 */
	enetaddr = ArpEther(binip,binenet,0);
	if (!enetaddr) {
		printf("ARP failed for %s\n",syslogsrvr);
		return(0);
	}

	/* Retrieve an ethernet buffer from the driver and populate the
	 * ethernet level of packet:
	 */
	enetp = (struct ether_header *) getXmitBuffer();
	memcpy((char *)&enetp->ether_shost,(char *)BinEnetAddr,6);
	memcpy((char *)&enetp->ether_dhost,(char *)binenet,6);
	enetp->ether_type = ecs(ETHERTYPE_IP);

	/* Move to the IP portion of the packet and populate it
	 * appropriately:
	 */
	ipp = (struct ip *) (enetp + 1);
	ipp->ip_vhl = IP_HDR_VER_LEN;
	ipp->ip_tos = 0;
	ip_len = sizeof(struct ip) + sizeof(struct Udphdr) + msglen;
	ipp->ip_len = ecs(ip_len);
	ipp->ip_id = ipId();
	ipp->ip_off = 0;
	ipp->ip_ttl = UDP_TTL;
	ipp->ip_p = IP_UDP;
	memcpy((char *)&ipp->ip_src.s_addr,(char *)BinIpAddr,4);
	memcpy((char *)&ipp->ip_dst.s_addr,(char *)binip,4);

	/* Now UDP...
	 */
	sport = port+1;
	udpp = (struct Udphdr *) (ipp + 1);
	udpp->uh_sport = ecs(sport);
	udpp->uh_dport = ecs(port);
	udpp->uh_ulen = ecs((ushort)(ip_len - sizeof(struct ip)));

	/* Finally, the SYSLOG data ...
	 */
	syslogmsg = (uchar *)(udpp+1);
	strcpy((char *)syslogmsg,(char *)msg);

	ipChksum(ipp);			/* Compute csum of ip hdr */
	udpChksum(ipp);			/* Compute UDP checksum */

	sendBuffer(ETHERSIZE + IPSIZE + UDPSIZE + msglen);
	return(0);
}
예제 #13
0
파일: gdb.c 프로젝트: jrcatbagan/umon-old
/* processGDB():
 * This is the function that allows a remote gdb host to connect to
 * the monitor with gdb at the udp level.  The connection command in
 * gdb to do this is:
 *
 *	target remote udp:TARGET_IP:TARGET_PORT
 */
int
processGDB(struct ether_header *ehdr,ushort size)
{
	char	*gdbp;
	struct	ip *ihdr, *ti, *ri;
	struct	Udphdr *uhdr, *tu, *ru;
	struct	ether_header *te;

	/* If SHOW_GDB is set (via ether -vg), then we dump the trace to
	 * the console; otherwise, we use mtrace.
	 */
#if INCLUDE_ETHERVERBOSE
	if (EtherVerbose & SHOW_GDB)
		gdbTrace = printf;
	else
#endif
		gdbTrace = Mtrace;

	ihdr = (struct ip *)(ehdr + 1);
	uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr));
	gdbp = (char *)(uhdr + 1);
	size = ecs(uhdr->uh_ulen) - sizeof(struct Udphdr);

	/* Check for ACK/NAK here:
	 */
	if (size == 1) {
		if ((*gdbp == '+') || (*gdbp == '-')) {
			gdbTrace("GDB_%s\n",*gdbp == '+' ? "ACK" : "NAK");
			return(0);
		}
	}

	/* Copy the incoming udp payload (the gdb command) to gdbIbuf[]
	 * and NULL terminate it...
	 */
	memcpy((char *)gdbIbuf,(char *)gdbp,size);
	gdbIbuf[size] = 0;

	/* Now that we've stored away the GDB command request, we
	 * initially respond with the GDB acknowledgement ('+')...
	 */
	te = EtherCopy(ehdr);
	ti = (struct ip *) (te + 1);
	ri = (struct ip *) (ehdr + 1);
	ti->ip_vhl = ri->ip_vhl;
	ti->ip_tos = ri->ip_tos;
	ti->ip_len = ecs((1 + (sizeof(struct ip) + sizeof(struct Udphdr))));
	ti->ip_id = ipId();
	ti->ip_off = ri->ip_off;
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
		sizeof(struct in_addr));
	memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr),
		sizeof(struct in_addr));
	tu = (struct Udphdr *) (ti + 1);
	ru = (struct Udphdr *) (ri + 1);
	tu->uh_sport = ru->uh_dport;
	tu->uh_dport = ru->uh_sport;
	tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + 1));
	gdbp = (char *)(tu+1);
	*gdbp = '+';

	ipChksum(ti);		/* Compute checksum of ip hdr */
	udpChksum(ti);		/* Compute UDP checksum */

	sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + 
		sizeof(struct Udphdr) + 1);

	/* Wrap the processing of the incoming packet with a set/clear
	 * of the gdbUdp flag so that the other gdb code can act 
	 * accordingly.
	 */
	gdbUdp = 1;
	if (gdb_cmd(gdbIbuf) == 0) {
		gdbUdp = 0;
		return(0);
	}
	gdbUdp = 0;

	/* Add 1 to the gdbRlen to include the NULL termination.
	 */
	gdbRlen++;	


	/* The second respons is only done if gdb_cmd returns non-zero.
	 * It is the response to the gdb command issued by the debugger
	 * on the host.
	 */
	te = EtherCopy(ehdr);
	ti = (struct ip *) (te + 1);
	ri = (struct ip *) (ehdr + 1);
	ti->ip_vhl = ri->ip_vhl;
	ti->ip_tos = ri->ip_tos;
	ti->ip_len = ecs((gdbRlen + (sizeof(struct ip) + sizeof(struct Udphdr))));
	ti->ip_id = ipId();
	ti->ip_off = ri->ip_off;
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
		sizeof(struct in_addr));
	memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr),
		sizeof(struct in_addr));

	tu = (struct Udphdr *) (ti + 1);
	ru = (struct Udphdr *) (ri + 1);
	tu->uh_sport = ru->uh_dport;
	tu->uh_dport = ru->uh_sport;
	tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + gdbRlen));
	memcpy((char *)(tu+1),(char *)gdbRbuf,gdbRlen);

	ipChksum(ti);		/* Compute checksum of ip hdr */
	udpChksum(ti);		/* Compute UDP checksum */

	sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + 
		sizeof(struct Udphdr) + gdbRlen);

	return(1);
}
예제 #14
0
/* BOOTPStartup()
 *	The DHCPDISCOVER is issued as an ethernet broadcast.  IF the bootp
 *	flag is non-zero then just do a bootp request (a subset of the 
 *	DHCPDISCOVER stuff).
 */
int
BOOTPStartup(short seconds)
{
	struct	dhcphdr *dhcpdata;
	struct	bootphdr *bootpdata;
	struct	ether_header *te;
	struct	ip *ti;
	struct	Udphdr *tu;
	ushort	uh_ulen;
	int		optlen;

	/* Retrieve an ethernet buffer from the driver and populate the
	 * ethernet level of packet:
	 */
	te = (struct ether_header *) getXmitBuffer();
	memcpy((char *)&te->ether_shost,(char *)BinEnetAddr,6);
	memcpy((char *)&te->ether_dhost,(char *)BroadcastAddr,6);
	te->ether_type = ecs(ETHERTYPE_IP);

	/* Move to the IP portion of the packet and populate it appropriately: */
	ti = (struct ip *) (te + 1);
	ti->ip_vhl = IP_HDR_VER_LEN;
	ti->ip_tos = 0;
	ti->ip_id = 0;
	ti->ip_off = ecs(0x4000);	/* No fragmentation allowed */
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memset((char *)&ti->ip_src.s_addr,0,4);
	memset((char *)&ti->ip_dst.s_addr,0xff,4);

	/* Now udp... */
	tu = (struct Udphdr *) (ti + 1);
	tu->uh_sport = ecs(DhcpClientPort);
	tu->uh_dport = ecs(DhcpServerPort);

	/* First the stuff that is the same for BOOTP or DHCP... */
	bootpdata = (struct bootphdr *)(tu+1);
	dhcpdata = (struct dhcphdr *)(tu+1);
	dhcpdata->op = DHCPBOOTP_REQUEST;
	dhcpdata->htype = 1;
	dhcpdata->hlen = 6;
	dhcpdata->hops = 0;
	dhcpdata->seconds = ecs(seconds);
	memset((char *)dhcpdata->bootfile,0,
		sizeof(dhcpdata->bootfile));
	memset((char *)dhcpdata->server_hostname,0,
		sizeof(dhcpdata->server_hostname));

	/* For the first request issued, establish a transaction id based
	 * on a crc32 of the mac address.  For each request after that,
	 * just increment.
	 */
	if (!BOOTPTransactionId)
		BOOTPTransactionId = BinEnetAddr[5];
	else
		BOOTPTransactionId++;

	memcpy((char *)&dhcpdata->transaction_id,(char *)&BOOTPTransactionId,4);
	memset((char *)&dhcpdata->client_ip,0,4);
	memset((char *)&dhcpdata->your_ip,0,4);
	memset((char *)&dhcpdata->server_ip,0,4);
	memset((char *)&dhcpdata->router_ip,0,4);
	memcpy((char *)dhcpdata->client_macaddr,(char *)BinEnetAddr,6);
	dhcpdata->flags = 0;

	self_ecs(dhcpdata->flags);

	/* Finally, the DHCP or BOOTP specific stuff...
	 * Based on RFC1534 (Interoperation Between DHCP and BOOTP), any message
	 * received by a DHCP server that contains a 'DHCP_MESSAGETYPE' option
	 * is assumed to have been sent by a DHCP client.  A message without the
	 * DHCP_MESSAGETYPE option is assumed to have been sent by a BOOTP
	 * client.
	 */
	uh_ulen = optlen = 0;
	memset((char *)bootpdata->vsa,0,sizeof(bootpdata->vsa));
	uh_ulen = sizeof(struct Udphdr) + sizeof(struct bootphdr);
	tu->uh_ulen = ecs(uh_ulen);
	ti->ip_len = ecs((sizeof(struct ip) + uh_ulen));

	ipChksum(ti);	/* Compute checksum of ip hdr */
	udpChksum(ti);	/* Compute UDP checksum */

	DHCPState = BOOTPSTATE_REQUEST;
	sendBuffer(BOOTPSIZE);

	return(0);
}