📄 ip_udp_arp.c
字号:
#include <probe.h>
#include <drv_intf.h>
#include <pna.h>
#include <sysvars.h> /* SysVars' declaration */
#include <ni.h>
#include <string.h>
#include <sys\\sockcom.h>
#include <sys\\socket.h>
#include <sys\\sockio.h>
#include "sys_conf.h"
#include <src\board.h>
#include <icontrol\mpc8xx.h>
#include "..\inc\ip_udp.h"
#include <lan/lan8xx.c>
#include "..\inc\web.h"
#include "..\inc\arpip.h"
extern ULONG LOCAL_MMC_CONNECT;
/************************************************************************************/
#define ARP_TIMER_PRECISION 200 /* the timer precision is 200ms */
/************************************************************************************/
#define ARP_TIMER_NOTIMEOUT -1
#define ARP_TIMER_RESEND 1000 /* 1s */
#define ARP_TIMER_TIMEOUT 600000 /* 600s (10 minute) */
/* ToS configure pf TCP HEAD */
/*111 - Network Control
110 - Internetwork Control
101 - CRITIC/ECP
100 - Flash Override
011 - Flash
010 - Immediate
001 - Priority
000 - Routine
*/
UCHAR TOS_Priority =0xa0;
UCHAR TOS_D=0x10;
UCHAR TOS_T=0;
UCHAR TOS_R=0;
UCHAR comid[24]={'I', 'P', 'B', 'X', 0, 0, 0, 0, 0, 0, 0, 0,
'I', 'P', 'B', 'X', 0, 0, 0, 0, 0, 0, 0, 0};
/************************************************************************************/
ARP_ENTRY arp_entry_table[ARP_TABLE_SIZE];
ULONG qid_arp = 0, tid_arp_recv = 0;
ULONG arperr = 0;
extern UDP_DATA_BUFF ras_to_udp_send;
extern char CENTER_STRING;
extern struct _BN_XN_TRANSTABLE
{
USHORT cmd;
USHORT total;
struct /* M(5@J}>]=a99 */
{
ULONG bn;
ULONG xn;
ULONG ip;
}BN_XN[120];
}BN_XN_TRANSTABLE;
extern struct {
ULONG TYPE;
UCHAR DN[16];
ULONG IP;
ULONG R_IP;
}LOCAL_RECORD_IP_TABLE;
extern unsigned char EthernetAddress[]; /* defined in our bsp's src/board.c */
void task_arp_pkt_recv(void);
void arp_send_pkt(ULONG ip);
ARP_ENTRY * arp_find_entry(ULONG ip);
ARP_ENTRY * arp_find_a_free_entry(void);
ULONG UdpCount;
int init_udp(int s);
void udp_rece(void);
extern char * arp_out(ULONG ip);
int SendToIp(ULONG dst_ip_addr,
USHORT dst_udp_port,
USHORT src_udp_port,
UCHAR * buf,
int len);
////////////////////////////////////////////////////
extern ConfigData configdata;
ULONG udp_setup=0;
USHORT datagram_id = 0;
extern ULONG VOIP_ID;
extern ULONG LOCAL_IP_ADDR;
#define IP_PLUS_UDP_HEADER_LEN 28
extern struct
{
ULONG flag;
ULONG ip;
ULONG voip;
ULONG port;
ULONG end; /** HANWEI ADD IN 2001.3.9 Used To Indicate The End of Talk : 0 -- Default; 1 -- Talk End **/
}UDP_ATTR[25];
typedef struct _IP_HEADER {
UCHAR ip_verlen; /* Ip version (4bit) header lengtn(4bit) */
UCHAR ip_tos; /* type of service(8bit) */
USHORT ip_len; /* total packet length(16bit) */
USHORT ip_id; /* datagram id(16bit) */
USHORT ip_fragoff; /* fragment offset(13bit) */
UCHAR ip_ttl; /* ttl(8bit) */
UCHAR ip_proto; /* ip protocol(8bit) */
USHORT ip_chksum; /* header checksum(16bit) */
ULONG ip_src; /* ip address of source(32bit) */
ULONG ip_dst; /* ip address of destination(32bit) */
UCHAR ip_data[1]; /* variavle length data */
} IP_HEADER;
typedef struct _UDP_HEADER {
USHORT udp_src_port;
USHORT udp_dst_port;
USHORT udp_pkt_len;
USHORT udp_chksum;
UCHAR udp_data[1];
} UDP_HEADER;
typedef struct _TCP_HEADER {
USHORT tcp_src_port;
USHORT tcp_dst_port;
ULONG tcp_seq;
ULONG tcp_ack_num;
USHORT tcp_pkt_len;
USHORT tcp_window;
USHORT tcp_chksum;
USHORT tcp_eme_point;
ULONG tcp_option;
UCHAR tcp_data[1];
} TCP_HEADER;
/***********************************************************************************/
#define IPT_UDP 17 /* protocol type for udp packets (added by lichunlin) */
USHORT UdpChecksum(IP_HEADER * ip);
int port[UDP_PORT_MAX_NUM];
int udp_share_sock_send[UDP_PORT_MAX_NUM];
int udp_share_sock_rece[UDP_PORT_MAX_NUM];
//UDP_DATA_BUFF app_to_udp_send[UDP_DATA_MAX_SEND_BUFF_NUM];
//UDP_DATA_BUFF udp_rece_to_app[UDP_DATA_MAX_RECE_BUFF_NUM];
UDP_DATA_BUFF app_to_udp_send[UDP_DATA_MAX_SEND_BUFF_NUM];
UDP_DATA_BUFF udp_rece_to_app[UDP_DATA_MAX_RECE_BUFF_NUM];
ULONG udp_send_quene_ID, udp_rece_quene_ID;
int init_arp(void)
{
ULONG rc;
memset(arp_entry_table, 0, sizeof(arp_entry_table));
if ((rc = q_create("QARP", 0, Q_FIFO | Q_SYSBUF | Q_NOLIMIT, &qid_arp)) != 0)
{
Print("init_mgarp: Cannot create queue QARP. Errno: %d\n.", rc);
return -1;
}
if ((rc = t_create("TARP", 150, 4096, 2048, 0, &tid_arp_recv)) != 0)
{
Print("init_mgarp: Cannot create task TARP. errno: 0x%04X\n.", rc);
return -1;
}
if ((rc = t_start(tid_arp_recv, T_SUPV | T_PREEMPT | T_NOTSLICE | T_NOISR , task_arp_pkt_recv, 0)) != 0)
{
Print("init_mgarp: Cannot start task TARP. errno: 0x%04X\n.", rc);
return -1;
}
return 0;
}
/* ----------------------------------------------------------------------- *\
|* Function:
|* task_arp_pkt_recv()
|*
|* Description:
|* This function is a task, it receive ARP packet from QUEUE qid_arp,
|* and update the ARP table.
|*
|* Argument:
|* none
|*
|* Return Value:
|* none
\* ----------------------------------------------------------------------- */
void task_arp_pkt_recv(void)
{
mblk_t * m;
ARP_PKT * arp;
ARP_ENTRY * pae;
ULONG rc, msg_buf[4];
int i, j=0;
while (1)
{
tm_wkafter(20); /*sleep_a_while(ARP_TIMER_PRECISION);*/
/* timer operation */
for (i = 0; i < ARP_TABLE_SIZE; i++)
{
pae = &arp_entry_table[i];
switch (pae->ae_state)
{
case AS_RESOLVED:
if (pae->ae_ttl != ARP_TIMER_NOTIMEOUT && pae->ae_reference <= 0)
{
pae->ae_ttl -= ARP_TIMER_PRECISION;
if (pae->ae_ttl <= 0)
pae->ae_state = AS_FREE;
}
break;
case AS_PENDING:
pae->ae_ttl -= ARP_TIMER_PRECISION;
if (pae->ae_ttl <= 0)
{
if (--pae->ae_attempts <= 0)
pae->ae_state = AS_FREE;
else
{
UCHAR * ip = (UCHAR *) &pae->ae_ipaddr;
/* Print("Resend an ARP request packet for IP addr %d.%d.%d.%d (0x%08X).\n",
ip[0], ip[1], ip[2], ip[3], pae->ae_ipaddr);
*/
pae->ae_ttl = ARP_TIMER_RESEND;
arp_send_pkt(pae->ae_ipaddr);
}
}
break;
case AS_FREE:
default:
break;
}
}
/*
if (arperr != 0)
{
Print("arp error = %d\n", arperr);
arperr = 0;
}
*/ while ((rc = q_receive(qid_arp, Q_NOWAIT, 0, msg_buf)) == 0)
{
switch (msg_buf[0])
{
case 1:/*ARP_MSG_INCREASE_REFERENCE:*
/*Print("Received ARP_MSG_INCREASE_REFERENCE for IP (0x%08X).\n", msg_buf[1]);*/
pae = arp_find_entry(msg_buf[1]);
if (pae == NULL)
{
UCHAR * ip = (UCHAR *)&msg_buf[1];
Print("Send an ARP request packet for IP addr %d.%d.%d.%d (0x%08X).\n",
ip[0], ip[1], ip[2], ip[3], msg_buf[1]);
pae = arp_find_a_free_entry();
if (pae == NULL)
{
Print("task_arp_pkt_recv: error! cannot find a free entry for IP(0x%08x)!\n", msg_buf[1]);
continue;
}
pae->ae_state = AS_PENDING;
pae->ae_ipaddr = msg_buf[1];
pae->ae_reference = 0;
pae->ae_attempts = 4;
pae->ae_ttl = ARP_TIMER_RESEND;
arp_send_pkt(pae->ae_ipaddr);
}
pae->ae_reference++;
break;
case 2:/*ARP_MSG_DECREASE_REFERENCE:*/
/*Print("Received ARP_MSG_DECREASE_REFERENCE for IP (0x%08X).\n", msg_buf[1]);*/
pae = arp_find_entry(msg_buf[1]);
if (pae != NULL)
{
if (pae->ae_reference > 0)
pae->ae_reference--;
}
break;
default: /* we received an ARP packet */
{
char * addr;
int i = 0;
m = (mblk_t *) msg_buf[0];
arp = (ARP_PKT *) m->b_rptr;
/* Print("\t%08X %08X %08X %08X\n", msg_buf[0], msg_buf[1], msg_buf[2], msg_buf[3]);
for (addr = m->b_rptr; addr < m->b_wptr; addr++)
{
Print("%02X ", *addr);
if (++i % 16 == 0)
Print("\n");
}
Print("\n");
Print("\tRead pointer: 0x%08X\n", (ULONG)m->b_rptr);
Print("\tWrite pointer: 0x%08X\n", (ULONG)m->b_wptr);
Print("\tContinue: %d\n", m->b_cont);
Print("It's an ARP packet:\n");
Print("\tType: %d\n", arp->arp_op);
addr = (char *)arp->arp_src_ipaddr;
Print("\tsrc IP addr: %03d.%03d.%03d.%03d\n", addr[0], addr[1], addr[2], addr[3]);
addr = (char *)arp->arp_src_hwaddr;
Print("\tsrc MAC addr: %02X:%02X:%02X:%02X:%02X:%02X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
addr = (char *)arp->arp_dst_ipaddr;
Print("\tdst IP addr: %03d.%03d.%03d.%03d\n", addr[0], addr[1], addr[2], addr[3]);
addr = (char *)arp->arp_dst_hwaddr;
Print("\tdst MAC addr: %02X:%02X:%02X:%02X:%02X:%02X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
*/ if ( arp->arp_hwtype != 1 /* Ethernet hardware type code */
|| arp->arp_prtype != 2048 /* ARP Packet Protocol Type */
|| arp->arp_hwlen != 6 /* Ethernet hardware address length (bytes) */
|| arp->arp_prlen != 4 /* IP address length (bytes) */
|| *(ULONG *)arp->arp_dst_ipaddr != SysVars.Lan1IP)
{
pna_freemsg(m);
continue;
}
{
UCHAR * ip = arp->arp_src_ipaddr;
/* Print("Received an ARP %s packet from IP addr %d.%d.%d.%d (0x%08X).\n",
arp->arp_op == 1 ? "request" : (arp->arp_op == 2 ? "reply" : "UNKNOWN"),
arp->arp_src_ipaddr[0], arp->arp_src_ipaddr[1], arp->arp_src_ipaddr[2], arp->arp_src_ipaddr[3],
*(ULONG *)arp->arp_src_ipaddr);
*/
}
pae = arp_find_entry(*(ULONG *)arp->arp_src_ipaddr);
if (pae == NULL)
{
/* Print("cannot find an entry for IP 0x%08X.\n", *(ULONG *)arp->arp_src_ipaddr);*/
pae = arp_find_a_free_entry();
if (pae == NULL)
{
Print("task_arp_pkt_recv: error! cannot find a free entry for IP(0x%08x)!\n", *(ULONG *)arp->arp_src_ipaddr);
continue;
}
pae->ae_ipaddr = *(ULONG *)arp->arp_src_ipaddr;
}
memcpy(pae->ae_hwaddr, arp->arp_src_hwaddr, 6);
if (pae->ae_ipaddr == SysVars.DefGtwyIP)
pae->ae_ttl = ARP_TIMER_NOTIMEOUT;
else
pae->ae_ttl = ARP_TIMER_TIMEOUT;
pae->ae_state = AS_RESOLVED;
/* Print("ARP entry:\n\t0x%08X %02X:%02X:%02X:%02X:%02X:%02X\n",
*(ULONG *)arp->arp_src_ipaddr,
arp->arp_src_hwaddr[0],
arp->arp_src_hwaddr[1],
arp->arp_src_hwaddr[2],
arp->arp_src_hwaddr[3],
arp->arp_src_hwaddr[4],
arp->arp_src_hwaddr[5]);
*/
if (arp->arp_op == 1) /* AR_REQUEST */
{
char macaddr[6];
arp->arp_op = 2; /* AR_REPLY */
memcpy(arp->arp_dst_hwaddr, arp->arp_src_hwaddr, 6);
*(ULONG *)arp->arp_dst_ipaddr = *(ULONG *)arp->arp_src_ipaddr;
memcpy(arp->arp_src_hwaddr, EthernetAddress, 6);
*(ULONG *)arp->arp_src_ipaddr = SysVars.Lan1IP;
/* arp->arp_dst_ipaddr[4] = 0xFF;
arp->arp_dst_ipaddr[5] = 0xEE;
arp->arp_dst_ipaddr[6] = 0xDD;
arp->arp_dst_ipaddr[7] = 0xCC;
arp->arp_dst_ipaddr[8] = 0xBB;
*/
memcpy(macaddr, arp->arp_dst_hwaddr, 6);
ni_send(macaddr, (char *)m, (USHORT)28, (USHORT)0x0806); /* ARP */
}
else /* AR_REPLY */
(*pNA_anounce_packet)((ULONG)0x0806, (char *)msg_buf[0], msg_buf[1], 1,
(char *)msg_buf[2], (char *)msg_buf[3]);
}
break;
}
}
if (rc != 0x37) /* ERR_NOMSG */
Print("task_arp_pkt_recv: ARPPKT queue receiving error, errno: 0x%04X.\n", rc);
}
}
/* ----------------------------------------------------------------------- *\
|* Function:
|* arp_send_pkt()
|*
|* Description:
|* Broadcast an ARP request packet for the specified IP address.
|*
|* Argument:
|* in: ULONG ip: ip address to send ARP request packet
|*
|* Return Value:
|* none
\* ----------------------------------------------------------------------- */
void arp_send_pkt(ULONG ip)
{
char broadcast_addr[6] = {255, 255, 255, 255, 255, 255};
ARP_PKT * arp;
mblk_t * m;
m = pna_allocb(28, PNA_TXQ_MEMPOOL); /* ARP packet length is 28 */
if (m == NULL)
{
Print("arp_send_pkt: pna_allocb() error! errno: 0x%04X\n", errno);
return;
}
arp = (ARP_PKT *)m->b_wptr;
arp->arp_hwtype = 1; /* Ethernet hardware type code */
arp->arp_prtype = 0x800; /* ARP Packet Protocol Type */
arp->arp_hwlen = 6; /* Ethernet hardware address length (bytes) */
arp->arp_prlen = 4; /* IP address length (bytes) */
arp->arp_op = 1; /* AR_REQUEST */
memcpy(arp->arp_src_hwaddr, EthernetAddress, 6);
*(ULONG *)arp->arp_src_ipaddr = SysVars.Lan1IP;
memset(arp->arp_dst_hwaddr, 0, 6);
*(ULONG *)arp->arp_dst_ipaddr = ip;
m->b_wptr += 28;
m->b_cont = 0;
ni_send(broadcast_addr, (char *)m, (USHORT)28, (USHORT)0x0806); /* ARP */
}
ARP_ENTRY * arp_find_entry(ULONG ip)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -