/*********************************************************************
 * Function:        void IP_RxHandler( NET_PKT *sbfr )
 *
 * PreCondition:    None
 * Input:			sbfr - packet buffer
 * Output:          None
 * Side Effects:    None
 * Overview:        Process new IP packet received by local NIC
 * Note:
 ********************************************************************/
void IP_RxHandler( NET_PKT *sbfr, BYTE * srcMAC )
{
    IP_HEADER *ipHdr;
    WORD len, optionsLen;
	BYTE ihl;
	
	// If this packet is not for us then discard it.
	// we may get these packets only in promiscous mode
    if( sbfr->PktType == PKT_NON_LOCAL )
    {
		goto IP_DropPkt;
	}

	ipHdr = (IP_HEADER*)sbfr->pNetworkLayer;

    ihl = ipHdr->IHL_Version & 0x0F;
    
    if( (ihl < IP_IHLEN) || ((ipHdr->IHL_Version & 0xF0) != IPv4) )
    {
		goto IP_DropPkt;
	}

    // Calculate options length in this header, if there is any.
    // IHL is in terms of numbers of 32-bit DWORDs; i.e. actual
    // length is 4 times IHL.
   
   
    optionsLen = (ihl * 4) - sizeof(IP_HEADER);

    if( optionsLen > MAX_OPTIONS_LEN )
    {
		goto IP_DropPkt;
	}
        
    if( checksum16( (BYTE*)ipHdr, ihl * 4 ) != 0xFFFF )  // must be FFFF
    {
		goto IP_DropPkt;
    }

    len = swaps( ipHdr->TotalLength );
        
    if( (sbfr->PktLen < len) || (len < (ihl * 4) ) )
    {
		goto IP_DropPkt;
    }

	ipHdr->TotalLength=sbfr->PktLen = len; //adjust pktlen to not exceed totallength
	IP_DeliverLocalPkt( sbfr );
	return;

//////////////////////////////////
IP_DropPkt:
   	DeAllocateBuffer(sbfr);
   	return;

}
Exemplo n.º 2
0
void _Network::tick()
{
	static unsigned short tx_to=0;
	static unsigned short rx_to=0;
	struct ethernet_packet rx;
	unsigned short len;
	unsigned short i;
	ENC28J60 *iface;
	struct arp_packet *arp;
	struct ip_packet *ip;
	struct icmp_packet *icmp;
	struct udp_packet *udp;
	struct tcp_packet *tcp;
	char temp[100];
	unsigned long spa,tpa;
	unsigned char *ipdata;
	unsigned short ipdlen;
	unsigned short ipdoff;
	TCPClient *cli;
	TCPServer *svr;
	TCPClient *est;

	if(rx_to>0)
	{
		rx_to--;
		if(rx_to==0)
		{
			digitalWrite(PIN_LED1,LOW);
		}
	}

	if(tx_to>0)
	{
		tx_to--;
		if(tx_to==0)
		{
			digitalWrite(PIN_LED2,LOW);
		}
	}

	for(i=0; i<MAX_INTERFACES; i++)
	{
		if(this->interfaces[i]!=NULL)
		{
			iface = this->interfaces[i];
			len = iface->packetReceive(1500,(unsigned char *)&rx);
			if(len>0)
			{
				iface->rx_packets++;
				// Handle the incoming packet
				digitalWrite(PIN_LED1,HIGH);
				rx_to = 10;
				switch(ntohs(rx.header.ether_type))
				{
					case ETHERTYPE_ARP:
						arp = (struct arp_packet *)rx.payload;
						spa = arp->spa[0]<<24 | arp->spa[1]<<16 | arp->spa[2]<<8 | arp->spa[3];
						tpa = arp->tpa[0]<<24 | arp->tpa[1]<<16 | arp->tpa[2]<<8 | arp->tpa[3];
						if(tpa == iface->ip)
						{
							this->addOrUpdateARP(arp->sha,spa,i);
							if(ntohs(arp->op) == ARP_OP_REQUEST)
							{
								// Someone is looking for us.
								memcpy(arp->tha,arp->sha,6);
								memcpy(arp->tpa,arp->spa,4);
								memcpy(arp->sha,iface->mac,6);
								arp->spa[3] = iface->ip & 0xFF;
								arp->spa[2] = iface->ip>>8 & 0xFF;
								arp->spa[1] = iface->ip>>16 & 0xFF;
								arp->spa[0] = iface->ip>>24 & 0xFF;
								memcpy(rx.header.ether_dhost,rx.header.ether_shost,6);
								memcpy(rx.header.ether_shost,iface->mac,6);
								arp->op = htons(ARP_OP_REPLY);

								iface->queueTX((unsigned char *)&rx,len);
							}
						}
						break;
					case ETHERTYPE_IP:
						ip = (struct ip_packet *)rx.payload;

						ipdoff = ip->ihl << 2;
						ipdlen = ntohs(ip->tot_len) - ipdoff;
						ipdata = (unsigned char *)(&rx.payload)+ipdoff;
						switch(ip->protocol)
						{
							case IPPROTO_ICMP:
								icmp = (struct icmp_packet *)ipdata;

								switch(icmp->type)
								{
									case ICMP_ECHO:
										icmp->type = ICMP_ECHOREPLY;
										memcpy(rx.header.ether_dhost,rx.header.ether_shost,6);
										memcpy(rx.header.ether_shost,iface->mac,6);
										memcpy(ip->daddr,ip->saddr,4);
										ip->saddr[3] = iface->ip & 0xFF;
										ip->saddr[2] = iface->ip>>8 & 0xFF;
										ip->saddr[1] = iface->ip>>16 & 0xFF;
										ip->saddr[0] = iface->ip>>24 & 0xFF;
										
										icmp->checksum = 0;
										icmp->checksum = htons(checksum16(ipdata,ipdlen,CS_IP));

										iface->queueTX((unsigned char *)&rx,len);
										break;
								}
								break;
							case IPPROTO_UDP:
								udp = (struct udp_packet *)ipdata;
								for(i=0; i<MAX_PORTS; i++)
								{
									if(this->udp_ports[i] != NULL)
									{
										if(this->udp_ports[i]->port == ntohs(udp->destPort))
										{
											this->udp_ports[i]->addPacket(len,&rx);
										}
									}
								}
								break;
							case IPPROTO_TCP:
								tcp = (struct tcp_packet *)ipdata;
								for(i=0; i<MAX_PORTS; i++)
								{
									if(this->tcp_clients[i]!=NULL)
									{
										if(this->tcp_clients[i]->socketMatch(ntohs(tcp->destPort), ntohs(tcp->sourcePort), 
											quad2ip(ip->saddr[0],ip->saddr[1],ip->saddr[2],ip->saddr[3]))==1)
										{
											cli = this->tcp_clients[i];
											cli->handleIncomingPacket(ip);
										}
									}
									if(this->tcp_servers[i]!=NULL)
									{
										// Packet coming in to a listening socket
										if((this->tcp_servers[i]->localPort == ntohs(tcp->destPort)) &&
											(this->tcp_servers[i]->state == TCP_LISTEN))
										{
											svr = this->tcp_servers[i];
											// Try and match it with an existing connection
											cli = NULL;
											for(i=0; i<MAX_TCP_CONNECTIONS; i++)
											{
												if(svr->connections[i].state!=TCP_CLOSED)
												{
													if(svr->connections[i].socketMatch(ntohs(tcp->destPort), ntohs(tcp->sourcePort), 
														quad2ip(ip->saddr[0],ip->saddr[1],ip->saddr[2],ip->saddr[3]))==1)
													{
														cli = &svr->connections[i];
														cli->handleIncomingPacket(ip);
													}
												}
											}
											// Not an existing connections.  If it's a SYN then start a connection up
											if(cli==NULL)
											{
												if(tcp->syn==1 && tcp->ack==0)
												{
													est = svr->getFreeConnection();
													if(est!=NULL)
													{
														est->localPort = svr->localPort;
														est->peerPort = ntohs(tcp->sourcePort);
														est->peerAddress = quad2ip(ip->saddr[0],ip->saddr[1],ip->saddr[2],ip->saddr[3]);
														est->tx_mss=1440;
														est->irs = ntohl(tcp->sequence);
														est->rx_nxt = est->irs+1;
														est->iss = rand();
														est->tx_nxt = est->iss;
														est->sendSynAck();
														est->state=TCP_ESTABLISHED;
													}
												}
											}
										}
									}
								}
								break;
							default:
								break;
						}
						break;
					default:
						break;
				}
Exemplo n.º 3
0
short UDP::send(unsigned long peerAddress, unsigned short peerPort, unsigned char *data, unsigned short len)
{
	short interface;
	struct ethernet_packet eth;
	unsigned long ipAddress = peerAddress;
	short rv;
	struct ip_packet *ip; 
	unsigned char *ipdata;
	struct udp_packet *udp;
	unsigned char *udpdata;

	interface = Network.getInterfaceByIP(peerAddress);
	if(interface<0)
	{
		interface = Network.getDefaultInterface();
	}
	if(interface<0)
	{
		return -ENROUTE;
	}

	memset((char *)&eth,0,sizeof(struct ethernet_packet));
	eth.header.ether_type=htons(ETHERTYPE_IP);
	memcpy(eth.header.ether_shost,Network.interfaces[interface]->mac,6);
	rv = Network.getARP(ipAddress,(unsigned char *)eth.header.ether_dhost,interface);
	if(rv < 0)
	{
		return -ENARP;
	}
	ip = (struct ip_packet *)(&eth.payload);
	ip->protocol = IPPROTO_UDP;
	ip->ttl = 64;
	ip->tos = 0;
	ip->id = htons(Network.interfaces[interface]->id());
	ip->flags = 0b010;
	ip->frag_off = 0;
	ip->frag_offh = 0;
	ip->saddr[3] = Network.interfaces[interface]->ip & 0xFF;
	ip->saddr[2] = Network.interfaces[interface]->ip>>8 & 0xFF;
	ip->saddr[1] = Network.interfaces[interface]->ip>>16 & 0xFF;
	ip->saddr[0] = Network.interfaces[interface]->ip>>24 & 0xFF;
	ip->daddr[3] = ipAddress & 0xFF;
	ip->daddr[2] = ipAddress>>8 & 0xFF;
	ip->daddr[1] = ipAddress>>16 & 0xFF;
	ip->daddr[0] = ipAddress>>24 & 0xFF;
	ip->version = 4;
	ip->ihl = 5;
	ip->tot_len = htons(sizeof(struct udp_packet) + 20 + len);
	ip->check = 0;
	ipdata = (unsigned char *)ip + 20;
	udp = (struct udp_packet *)ipdata;
	udp->sourcePort = htons(this->port);
	udp->destPort = htons(peerPort);
	udp->checksum = 0;
	udp->length = htons(len+sizeof(udp_packet));
	udpdata = (unsigned char *)udp+sizeof(struct udp_packet);
	memcpy(udpdata,data,len);
	udp->checksum = htons(checksum16((unsigned char *)&ip->saddr[0],len+16,1));
	ip->check = htons(checksum16((unsigned char *)ip,20,CS_IP));


	Network.interfaces[interface]->queueTX((unsigned char *)&eth,sizeof(struct ether_header)+20+sizeof(struct udp_packet)+len);
	return len;
}
Exemplo n.º 4
0
void upload(char *filename, char *path, char *ip, int opt, unsigned short start, unsigned short exec)
{
	int ret, size, p, n, k, i, j;
	char fullpath[256];	// don't exceed this, the cpc wouldn't be able |cd it anyway 
	FILE *fd;
	
	SOCKET sd;
	
	unsigned char *buf;
	fd = fopen(filename, "rb");
	if ( fd == NULL )
	{	printf("file %s not found\n", filename);
		return;
	}

#ifndef __WIN32__
	if (!is_regular_file(filename))
	{	printf("file %s is not a regular file\n", filename);
		fclose(fd);
		return;
	}
#endif
	
	fseek(fd, 0, SEEK_END);
	size = ftell(fd);
	fseek(fd, 0, SEEK_SET);
	
	buf = malloc(size+0x80);
	if ( buf == NULL )
	{
		printf("Not enough memory!\n");
		fclose(fd);
		return;
	}
	
	if ( opt != 0 )
	{	_cpchead *cpcheader = (_cpchead *)buf;
		memset(cpcheader, 0, 0x80);
		
		// set up cleaned filename and extionsion
		formatfn(cpcheader->filename, filename);
		getExtension(cpcheader->extension, filename);
		
		// add more file types here... and more paramters....
		
		switch (opt)
		{
					
			
			case 1:
			cpcheader->addr = 0x172;	// protext uses this
			cpcheader->type = 10; 	
			cpcheader->size = size;
			cpcheader->size2 = size;
			cpcheader->checksum = checksum16(buf, 66);
			break;
			
			default:
			case 2:		// binary header
			cpcheader->addr = start;
			cpcheader->exec = exec;
			cpcheader->type = 2; 	
			cpcheader->size = size;
			cpcheader->size2 = size;
			cpcheader->checksum = checksum16(buf, 66);
			break;
			
		}
		
		fread(&buf[0x80], size, 1, fd);
		size+=0x80;
	}
	else
		fread(buf, size, 1, fd);
	
	fclose(fd);
	

	ret = httpConnect(ip);
	if ( ret >= 0 )
	{	sd = ret;	// connect socket
	
		p = pathPos(filename, strlen(filename));	// strip any PC path from filename
		sprintf(fullpath, "%s/%s", path, &filename[p]);
		
		k = strlen(fullpath);
		n = 0; 
		while ( n < k ) // remove leading / from path
		{
			if ( fullpath[n] != '/' )
				break;
			n++;
		}
		
		// remove duplicate /'s
	
		k = strlen(fullpath);
		j = 0;
		for (i=n; i < (k+1); i++)
		{
			if ( (fullpath[i] == '/') && (fullpath[i+1] == '/') )
				i++;
			
			fullpath[j++] = fullpath[i];
		}
		
		if ( httpSend(sd, fullpath, buf, size, "upfile", "/upload.html", ip) >= 0 )
			ret = httpResponse(sd);
		
		httpClose(sd);
		if ( ret == 200 )
			printf("Upload OK!\r\n");
		else
			printf("Upload error code. %i\r\n", ret);
	}
	else
		printf("Connect to %s failed\n", ip);

	free(buf);
}