📄 ethmod.c
字号:
{
/*port 7 is the well-known echo port*/
if(packet[UDP_destport] == 0x00 && packet[UDP_destport+1] ==0x07)
{
/*build the IP header*/
setipaddrs();
/*swap the UDP source and destination ports*/
data_L = packet[UDP_srcport];
packet[UDP_srcport] = packet[UDP_destport];
packet[UDP_destport] = data_L;
data_L = packet[UDP_srcport+1];
packet[UDP_srcport+1] = packet[UDP_destport+1];
packet[UDP_destport+1] = data_L;
/*calculate the UDP checksum*/
packet[UDP_cksum] = 0x00;
packet[UDP_cksum+1] = 0x00;
hdr_chksum =0;
hdrlen = 0x08;
addr = &packet[ip_srcaddr];
cksum();
hdr_chksum = hdr_chksum + packet[ip_proto];
hdrlen = 0x02;
addr = &packet[UDP_len];
cksum();
hdrlen = make16(packet[UDP_len],packet[UDP_len+1]);
addr = &packet[UDP_srcport];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[UDP_cksum] = make8(chksum16,1);
packet[UDP_cksum+1] = make8(chksum16,0);
/*echo the incoming data back to the VB program*/
echo_packet();
}
/*buttons on the VB GUI are pointed towards port address 5000 decimal*/
else if(packet[UDP_destport] == 0x13 && packet[UDP_destport+1] == 0x88);
{
if(packet[UDP_data])
/*received a 0x00 from the VB program*/
bit_set(PORTA,4);
else
/*received a 0xFF from the VB program*/
bit_clear(PORTA,4);
}
}
/******************************************************************
//* TCP Function
//* This function uses TCP protocol to act as a Telnet server on
//* port 8088 decimal. The application function is called with
//* every incoming character.
//******************************************************************/
void tcp()
{
/*assemble the destination port address from the incoming packet*/
portaddr = make16(packet[TCP_destport],packet[TCP_destport+1]);
/*calculate the length of the data coming in with the packet*/
/*tcpdatalen_in = incoming packet length - incoming ip header length - incoming tcp header length*/
tcpdatalen_in = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) -
((packet[ip_vers_len] & 0x0F) * 4) - (((packet[TCP_hdrflags] & 0xF0) >> 4) * 4);
/*If an ACK is recieved and the destination port address is valid and no data is in the packet*/
if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in == 0x00)
{
/*assemble the acknowledgment number from the incoming packet*/
incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
/*if the incoming packet is a result of session establishment*/
if(synflag)
{
/*clear the SYN flag*/
synflag = 0;
/*the incoming acknowledgment is my new sequence number*/
my_seqnum = incoming_ack;
/*send the Telnet server banner*/
/*limit the character count to 40 decimal*/
strcpy(packet[TCP_data],"EASY ETHERNET\r\n1=LED ON\r\n0=LED OFF\r\n>");
/*length of the banner message*/
tcpdatalen_out = 37;
/*expect to get an acknowledgment of the banner message*/
expected_ack = my_seqnum +tcpdatalen_out;
/*send the TCP/IP packet*/
send_tcp_packet();
}
}
/*if an ack is received and the port address is valid and there is data in the incoming packet*/
if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in)
{
for(i=0;i<tcpdatalen_in;++i)
{
/*receive the data and put it into the incoming data buffer*/
aux_data[i] = packet[TCP_data+i];
/*run the TCP application*/
application_code();
}
/*assemble the acknowledgment number from the incoming packet*/
incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
/*check for the number of bytes acknowledged*/
/*determine how many bytes are outstanding and adjust the outgoing sequence number accordingly*/
if(incoming_ack <= expected_ack)
my_seqnum = expected_ack - (expected_ack - incoming_ack);
/*my expected acknowledgement number*/
expected_ack = my_seqnum +tcpdatalen_out;
send_tcp_packet();
}
/*this code segment processes the incoming SYN from the Telnet client
/*and sends back the initial sequence number (ISN) and acknowledges
/*the incoming SYN packet*/
if(SYN_IN && portaddr == MY_PORT_ADDRESS)
{
tcpdatalen_in = 0x01;
synflag = 1;
setipaddrs();
data_L = packet[TCP_srcport];
packet[TCP_srcport] = packet[TCP_destport];
packet[TCP_destport] = data_L;
data_L = packet[TCP_srcport+1];
packet[TCP_srcport+1] = packet[TCP_destport+1];
packet[TCP_destport+1] = data_L;
assemble_ack();
if(++ISN == 0x0000 || ++ISN == 0xFFFF)
ISN = 0x1234;
my_seqnum = make32(ISN,0xFFFF);
set_packet32(TCP_seqnum,my_seqnum);
packet[TCP_hdrflags+1] = 0x00;
SYN_OUT;
ACK_OUT;
packet[TCP_cksum] = 0x00;
packet[TCP_cksum+1] = 0x00;
hdr_chksum =0;
hdrlen = 0x08;
addr = &packet[ip_srcaddr];
cksum();
hdr_chksum = hdr_chksum + packet[ip_proto];
tcplen = make16(packet[ip_pktlen],packet[ip_pktlen+1]) - ((packet[ip_vers_len] & 0x0F) * 4);
hdr_chksum = hdr_chksum + tcplen;
hdrlen = tcplen;
addr = &packet[TCP_srcport];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[TCP_cksum] = make8(chksum16,1);
packet[TCP_cksum+1] = make8(chksum16,0);
echo_packet();
}
/*this code segment processes a FIN from the Telnet client
/*and acknowledges the FIN and any incoming data.*/
if(FIN_IN && portaddr == MY_PORT_ADDRESS)
{
if(tcpdatalen_in)
{
for(i=0;i<tcpdatalen_in;++i)
{
aux_data[i] = packet[TCP_data+i];
application_code();
}
}
finflag = 1;
++tcpdatalen_in;
incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
if(incoming_ack <= expected_ack)
my_seqnum = expected_ack - (expected_ack - incoming_ack);
expected_ack = my_seqnum +tcpdatalen_out;
send_tcp_packet();
}
}
/******************************************************************
//* Assemble the Acknowledgment
//* This function assembles the acknowledgment to send to
//* to the client by adding the received data count to the
//* client's incoming sequence number.
//******************************************************************/
void assemble_ack()
{
client_seqnum=make32(packet[TCP_seqnum],packet[TCP_seqnum+1],packet[TCP_seqnum+2],packet[TCP_seqnum+3]);
client_seqnum = client_seqnum + tcpdatalen_in;
set_packet32(TCP_acknum,client_seqnum);
}
/******************************************************************
//* Send TCP Packet
//* This routine assembles and sends a complete TCP/IP packet.
//* 40 bytes of IP and TCP header data is assumed.
//******************************************************************/
void send_tcp_packet()
{
/*count IP and TCP header bytes.. Total = 40 bytes*/
ip_packet_len = 40 + tcpdatalen_out;
packet[ip_pktlen] = make8(ip_packet_len,1);
packet[ip_pktlen+1] = make8(ip_packet_len,0);
setipaddrs();
data_L = packet[TCP_srcport];
packet[TCP_srcport] = packet[TCP_destport];
packet[TCP_destport] = data_L;
data_L = packet[TCP_srcport+1];
packet[TCP_srcport+1] = packet[TCP_destport+1];
packet[TCP_destport+1] = data_L;
assemble_ack();
set_packet32(TCP_seqnum,my_seqnum);
packet[TCP_hdrflags+1] = 0x00;
ACK_OUT;
if(finflag)
{
FIN_OUT;
finflag = 0;
}
packet[TCP_cksum] = 0x00;
packet[TCP_cksum+1] = 0x00;
hdr_chksum =0;
hdrlen = 0x08;
addr = &packet[ip_srcaddr];
cksum();
hdr_chksum = hdr_chksum + packet[ip_proto];
tcplen = ip_packet_len - ((packet[ip_vers_len] & 0x0F) * 4);
hdr_chksum = hdr_chksum + tcplen;
hdrlen = tcplen;
addr = &packet[TCP_srcport];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[TCP_cksum] = make8(chksum16,1);
packet[TCP_cksum+1] = make8(chksum16,0);
txlen = ip_packet_len + 14;
if(txlen < 60)
txlen = 60;
data_L = make8(txlen,0);
data_H = make8(txlen,1);
write_creg(CR,0x22);
write_creg(TPSR,txstart);
write_creg(RSAR0,0x00);
write_creg(RSAR1,0x40);
write_creg(ISR,0xFF);
write_creg(RBCR0,data_L);
write_creg(RBCR1,data_H);
write_creg(CR,0x12);
for(i=0;i<txlen;++i)
write_creg(RDMAPORT,packet[enetpacketDest0+i]);
byte_read = 0;
while(!bit_test(byte_read,RDC))
read_creg(ISR);
write_creg(TBCR0,data_L);
write_creg(TBCR1,data_H);
write_creg(CR,0x24);
}
/******************************************************************
//* Read/Write for show_regs
//* This routine reads a NIC register and dumps it out to the
//* serial port as ASCII.
//******************************************************************/
void readwrite()
{
read_creg(i);
bin2hex(byte_read);
printf("\t%c%c",high_char,low_char);
}
/******************************************************************
//* Displays Control Registers in Pages 1, 2 and 3
//* This routine dumps all of the NIC internal registers
//* to the serial port as ASCII characters.
//******************************************************************/
void show_regs()
{
write_creg(CR,0x21);
cls();
printf("\r\n");
printf(" Realtek 8019AS Register Dump\n\n\r");
printf("REG\tPage0\tPage1\tPage2\tPage3\n\r");
for(i=0;i<16;++i)
{
bin2hex((char) i);
printf("%c%c",high_char,low_char);
write_creg(CR,0x21);
readwrite();
write_creg(CR,0x61);
readwrite();
write_creg(CR,0xA1);
readwrite();
write_creg(CR,0xE1);
readwrite();
printf("\r\n");
}
}
/******************************************************************
//* Dump Receive Ring Buffer Header
//* This routine dumps the 4-byte receive buffer ring header
//* to the serial port as ASCII characters.
//******************************************************************/
void dump_header()
{
for(i=0;i<4;++i)
{
bin2hex(pageheader[i]);
printf("\r\n%c%c",high_char,low_char);
}
}
/******************************************************************
//* Converts Binary to Displayable Hex Characters
//* ie.. 0x00 in gives 0x30 and 0x30 out
//******************************************************************/
void bin2hex(binchar)
{
high_nibble = (binchar & 0xF0) / 16;
if(high_nibble > 0x09)
high_char = high_nibble + 0x37;
else
high_char = high_nibble + 0x30;
low_nibble = (binchar & 0x0F);
if(low_nibble > 0x09)
low_char = low_nibble + 0x37;
else
low_char = low_nibble + 0x30;
}
/******************************************************************
//* Used with Tera Term to clear the screen (VT-100 command)
//******************************************************************/
void cls(void)
{
printf("%c[2J",esc);
}
/******************************************************************
//* show_packet
//* This routine is for diagnostic purposes and displays
//* the Packet Buffer memory in the PIC.
//******************************************************************/
void show_packet()
{
cls();
printf("\r\n");
data_L = 0x00;
for(i=0;i<96;++i)
{
bin2hex(packet[i]);
printf(" %c%c",high_char,low_char);
if(++data_L == 0x10)
{
data_L = 0x00;
printf("\r\n");
}
}
}
/******************************************************************
//* show_aux_packet
//* This routine is a diagnostic that displays Auxillary
//* Packet Buffer buffer memory in the PIC.
//******************************************************************/
void show_aux_packet()
{
cls();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -