⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 onu_dhcp.c

📁 dhcp snooping for vxworks
💻 C
字号:

int flag_dhcp_snooping = 0;
int flag_dhcp_option82 = 1;
char dhcp_trust_port [11];
int dhcp_snoop_debug;
int dhcp_option82_debug;
int dhcp_command_respons = 0;
char *p_dhcp_bind = NULL;


#define MAXPortNum2 32
#define UDP_SRC_PORT_OFFSET 34
#define PRINTFSNOOP if(dhcp_snoop_debug)printf
#define PRINTFOPTION82 if(dhcp_option82_debug)printf
#define PRINTFDHCP if(dhcp_option82_debug||dhcp_snoop_debug)printf
#define PPPOE_DISCOVERY 0x8863 
#define VLAN_8021Q 0x8100
#define MAC_ADDRESS_LENTH 6
#define MIN_PACKET_LENTH 60
#define VLAN_TAG_LENTH 4
#define IP_PROTOCOL 0x0800
#define PROTOCOL_OFFSET 12
#define PPPOE_FIRST_TLV_OFFSET 20
#define PPPOE_HEADER_LENTH_OFFSET 18
#define PPPOE_PORT_INFO_TAG 0x0105
#define PPPOE_PORT_INFO_LENTH 3
#define IP_PROTOCOL_OFFSET 23
#define UDP_PROTOCOL 17
#define UDP_SRC_PORT_OFFSET 34
#define DHCP_DEST_PORT_UDP 67
#define FIRST_DHCP_OPTION_OFFSET 282
#define DHCP_MESSAGE_TYPE_OPTION 53
#define DHCP_82_TYPE_OPTION 82

#define DHCP_TYPE_DISCOVERY 1
#define DHCP_TYPE_OFFER 2
#define DHCP_TYPE_REQUEST 3
#define DHCP_TYPE_DECLINE 4
#define DHCP_TYPE_ACK 5
#define DHCP_TYPE_NAK 6
#define DHCP_TYPE_RELEASE 7
#define DHCP_TYPE_INFORM 8
#define MAX_DHCP_SLOT_BIND_BUF 7000

enum DHCP_MESSAGE_TYPE
{
	DHCPDISCOVER 					= 1,
	DHCPOFFER 	 					= 2,
	DHCPREQUEST 					= 3,
	DHCPDECLINE						= 4,
	DHCPACK							= 5,
	DHCPNAK							= 6,
	DHCPRELEASE						= 7,
	DHCPINFORM						=8,

	INVALID_DHCP_MESSAGE_TYPE 		= 0xff
};


int add_option82_to_packet (char *packet, char *p_option82, u_char onu, char onuPort, char *mac, short origin_len, short *new_len, u_char offsetBrcm,u_char offsetVlan,)
{
	char buf[1400];
	char buf2[200];
	char *p;
	char option82_temp[300];
	char gsw_temp[100];
	unsigned short option_len, len;
	short len_change = 0;
	unsigned short old_len;
	char VlanTagOffset =0;

	memset (option82_temp, 0, sizeof (option82_temp));
	memset (buf, 0, sizeof (buf));
	memset (buf2, 0, sizeof (buf2));

	/*如果源包里没有option82,则将其添加到最后*/
	if (*p_option82 == 0xff)
	{
		sprintf (buf, "0 0/0/0:0.0 0/0/0/0/0/0 EPON%08d/0/0/%d EP", onu, onuPort);
		len = strlen(buf);
		len_change = len+ 4+2;
	}
	p = option82_temp;
	*p = 82; /*tag*/
	p++;
	*p = 4+ len; /*length of opton82 value, including 2 sub string*/
	if (*p >255)
	return -1;
	p++;
	*p = 1; /*sub string 01*/
	p++;
	*p = len; /*length of sub 01*/
	p++;
	memcpy (p, buf, len);
	p = p + len;
	*p = 2; /*sub string 02*/
	p++;
	*p = 0; /*length of sub 02*/
	p++;
	*p = 0xff; /*end of options*/
	p++;

	len = p- option82_temp;
	memcpy (p_option82, option82_temp, len);


	p = packet;
	len = *(short *)(packet+16+ offsetBrcm + offsetVlan);
	*(short *)(packet+ offsetBrcm + offsetVlan +16) = htons (len+ len_change);       /*new ip length*/
	CaculateChecksum((unsigned char *)(packet + 14 + offsetBrcm + offsetVlan),20,10);   /*calculate ip checksum*/

	len = *(short *)(packet+38+offsetBrcm + offsetVlan);
	*(short *)(packet+ offsetBrcm + offsetVlan +38) = htons (len+ len_change);       /*new udp length*/
	*(short *)(packet+ offsetBrcm + offsetVlan +40) = 0;                                         /*udp checksum set to 0*/ 

	*new_len = origin_len+ len_change;
}


/*return: -1 discard; 0 send new packet*/
int dhcp_receive (char *origin_packet, short len, char onuId, char onuPort, char *mac, u_char offsetBrcm,u_char offsetVlan, char *new_packet, short *new_len)
{
	char *p_origin = origin_packet;
	char VlanTagOffset = offsetVlan;
	unsigned short udp_dest_port = 0;
	unsigned short udp_src_port = 0;
	unsigned char /*OptionTag, */OptionLength;
	int OptionTag;
	char next_option_tag = 0;
	short option_tag_offset = 0;
	char type = 0;
	char *p_option82 = NULL;
	unsigned char option82_next_option;
	char *p, *p_end_option;

	PRINTFDHCP("receive dhcp pakcet slot = %d vlan=%d\r\n", slot, vlan);
	
	if(len<340)
	{
	       PRINTFDHCP("DHCP length %d less than 340!\n",len);
      	       return -1;
	}

	memcpy (new_packet, origin_packet, len);
	p_origin = new_packet;
		

       if(htons (*((short *) (p_origin + PROTOCOL_OFFSET + offsetBrcm + offsetVlan))) != IP_PROTOCOL)
       {
                PRINTFDHCP("Not IP Packet!\n");
                 return - 1;
       }

	if(*(p_origin + IP_PROTOCOL_OFFSET +  offsetBrcm + offsetVlan)) != UDP_PROTOCOL)
	{
	          PRINTFDHCP("Not UDP Packet!\n");
	           return -1;
	 }

	p = p_origin + UDP_SRC_PORT_OFFSET +  offsetBrcm + offsetVlan);
	udp_src_port = htons (*(unsigned short *)p);
	p = p_origin + UDP_SRC_PORT_OFFSET +  offsetBrcm + offsetVlan) + 2;
	udp_dest_port = htons (*(unsigned short *)p);
	if (udp_src_port != DHCP_DEST_PORT_UDP && udp_dest_port != DHCP_DEST_PORT_UDP)
	{
		PRINTFDHCP("Not DHCP Packet!\n");
	       return -1;
	}

	OptionTag = *(p_origin+ offsetBrcm + offsetVlan)+FIRST_DHCP_OPTION_OFFSET);
	OptionLength = *(p_origin+ offsetBrcm + offsetVlan)+FIRST_DHCP_OPTION_OFFSET + 1);
	option_tag_offset =  offsetBrcm + offsetVlan)+FIRST_DHCP_OPTION_OFFSET;
	while(OptionTag != 0xff)
	{
		switch (OptionTag)
		{
			case DHCP_MESSAGE_TYPE_OPTION:
				type = *(p_origin+option_tag_offset+2);
				PRINTFDHCP("type = %d\r\n", type);
				if (type == DHCP_TYPE_OFFER || type == DHCP_TYPE_ACK ||type == DHCP_TYPE_NAK )
				{
					if (flag_dhcp_snooping && dhcp_trust_port[slot-17]!=1)
					{
						PRINTFSNOOP ("dhcp snooping enable, untrusted port discard dhcp offer and ack packets\r\n");
						return -1;
				
					}
					else
					{
						PRINTFSNOOP("pass trusted port, send origin packet out1\r\n");
						return 1;
					}
				}
				break;

			case DHCP_82_TYPE_OPTION:
				p_option82 = option_tag_offset+p_origin;
				PRINTFOPTION82 ("diacard packet with option82 from unkown user\r\n");
				return -1;

			default:
				break;
		}
		OptionLength = *(p_origin+1+option_tag_offset);
		option_tag_offset = option_tag_offset + 2+ OptionLength;
		if (OptionTag == 82)
		{
			option82_next_option =  *(p_origin+option_tag_offset);
		}
		OptionTag = *(p_origin+option_tag_offset);
		if(option_tag_offset >1200)
		{
			PRINTFSNOOP("dhcp packet length more than 1200\r\n ");
			return -1;
		}
	}

	p_end_option = p_origin+option_tag_offset;

	if (type == DHCP_TYPE_DISCOVERY || type == DHCP_TYPE_REQUEST || type == DHCP_TYPE_DECLINE || type == DHCP_TYPE_INFORM || type == DHCP_TYPE_RELEASE)
	{
		if (flag_dhcp_option82)
		{
			add_option82_to_packet (new_packet, p_end_option, onuId, onuPort, mac, len, new_len, offsetBrcm, offsetVlan,);
		}
	}

	PRINTFDHCP("send origin packet out2\r\n");
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -