📄 onu_dhcp.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 + -