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

📄 net_ipv4_bootp.c

📁 bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	{ DHCP_LEASE_TIME,			DHCPOPT_INT32 },	{ DHCPOPTION_OVERLOAD,		DHCPOPT_INT8 },	{ DHCP_MESSAGE_TYPE,		DHCPOPT_INT8 },	{ DHCP_SERVER_ID,			DHCPOPT_INT32 },	{ DHCP_PARAM_REQUEST,		DHCPOPT_INT8 | DHCPOPT_LIST },	{ DHCP_MESSAGE,				DHCPOPT_STR },	{ DHCP_MAX_SIZE,			DHCPOPT_INT16 },	{ DHCP_T1,					DHCPOPT_INT32 },	{ DHCP_T2,					DHCPOPT_INT32 },	{ DHCP_VENDOR_CLASS_ID,		DHCPOPT_STR },	{ DHCP_CLIENT_ID,			DHCPOPT_VARIABLE },	{ DHCP_NISPLUS_DOMAIN,		DHCPOPT_STR },	{ DHCP_NISPLUS_SERVER,		DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_TFTP_SERVERNAME,		DHCPOPT_STR },	{ DHCP_BOOTFILE,			DHCPOPT_STR },	{ DHCP_MOBILE_IP_AGENT,		DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_SMTP_SERVER,			DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_POP3_SERVER,			DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_NNTP_SERVER,			DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_WWW_SERVER,			DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_FINGER_SERVER,		DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_IRC_SERVER,			DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_ST_SERVER,			DHCPOPT_IPADDR | DHCPOPT_LIST },	{ DHCP_ST_DA_SERVER,		DHCPOPT_IPADDR | DHCPOPT_LIST },	{ 0, 						0 },};/* OPTION : [code] [len] [data...] */#define DHCPOPT_CODE			0#define DHCPOPT_LEN				1#define DHCPOPT_DATA			2/*  * function prototypes */int dhcp_send_discover(unsigned int xid);int dhcp_send_request(unsigned int xid, in_addr_t ipaddr, in_addr_t serverid);void dhcp_init_packet(bootphdr_t *pbp, int type);void dhcp_add_request_option(bootphdr_t *pbp);void dhcp_option_appendstr(unsigned char *str, unsigned char *opt);void dhcp_option_add(unsigned char *str, int code, unsigned int data, int list);/* * DHCP protocol *//* Broadcast a DHCP discover packet to the network, with an optionally requested IP */int dhcp_send_discover(unsigned int xid){	bootpip_t packet;	dhcp_init_packet(&packet.bp, DHCPDISCOVER);	packet.bp.bp_xid = xid;	dhcp_add_request_option(&packet.bp);	return udp_transmit(INADDR_BROADCAST, IPPORT_BOOTP_CLIENT, IPPORT_BOOTP_SERVER, sizeof packet.bp, &packet);}int dhcp_send_request(unsigned int xid, in_addr_t ipaddr, in_addr_t serverid){	bootpip_t packet;	dhcp_init_packet(&packet.bp, DHCPREQUEST);	packet.bp.bp_xid = xid;	dhcp_option_add(packet.bp.bp_vend, DHCP_REQUESTED_IP, ipaddr, 0);	dhcp_option_add(packet.bp.bp_vend, DHCP_SERVER_ID, serverid, 0);	dhcp_add_request_option(&packet.bp);	return udp_transmit(INADDR_BROADCAST, IPPORT_BOOTP_CLIENT, IPPORT_BOOTP_SERVER, sizeof packet.bp, &packet);}/* * DHCP packet *//* initialize a packet with the proper defaults */void dhcp_init_packet(bootphdr_t *pbp, int type){	static char s_vendorid[] = "Sigma Designs Bootloader";	unsigned char clientid[8];	memset(pbp, 0, sizeof(bootphdr_t));	switch (type) {	case DHCPDISCOVER :	case DHCPREQUEST :	case DHCPRELEASE :	case DHCPINFORM :		pbp->bp_op = BOOTP_REQUEST;		break;	case DHCPOFFER :	case DHCPACK :	case DHCPNAK : 		pbp->bp_op = BOOTP_REPLY;		break;	}	pbp->bp_htype = 1;			// 10MB ethernet	pbp->bp_hlen = ETH_ALEN;	// 10MB ethernet	pbp->bp_ciaddr = htonl(g_arptable[ARP_CLIENT].ipaddr);	memcpy(pbp->bp_hwaddr, g_arptable[ARP_CLIENT].node, ETH_ALEN);		// DHCP magic code	*((unsigned int *) pbp->bp_vend) = htonl(DHCP_MAGIC);	pbp->bp_vend[4] = DHCP_END;	// DHCP options	dhcp_option_add(pbp->bp_vend, DHCP_MESSAGE_TYPE, type, 0);	dhcp_option_add(pbp->bp_vend, DHCP_VENDOR_CLASS_ID, (unsigned int) s_vendorid, 0);	clientid[0] = 1;	memcpy(clientid + 1, g_arptable[ARP_CLIENT].node, ETH_ALEN);	dhcp_option_add(pbp->bp_vend, DHCP_CLIENT_ID, (unsigned int) clientid, 7);}void dhcp_add_request_option(bootphdr_t *pbp){	static unsigned char s_request[] = {		DHCP_SUBNET, DHCP_ROUTER, DHCP_DNS_SERVER, DHCP_HOST_NAME, DHCP_DOMAIN_NAME, DHCP_BROADCAST };			dhcp_option_add(pbp->bp_vend, DHCP_PARAM_REQUEST, (unsigned int) s_request, sizeof s_request);}/* * DHCP options :  */void dhcp_option_appendstr(unsigned char *str, unsigned char *opt){	int i, len;	// look for the end of option	for (i = 4; str[i] != DHCP_END;) {		if (str[i] == DHCP_PADDING) 			++i;		else 			i += str[i + DHCPOPT_LEN] + 2;	}	len = opt[DHCPOPT_LEN] + 2;	memcpy(str + i, opt, len);	str[i + len] = DHCP_END;}// data : //   1, 2, 4 byte integer//   type casted pointer to string//   type casted pointer to array// list : //   0 : data is normal integer or pointer to string//   1 : data is array with one item//   > 1 : data is array with more than one item//   with the option type 'DHCPOPT_VARIABLE', list means size of arrayvoid dhcp_option_add(unsigned char *str, int code, unsigned int data, int list){	int i, len, copylen;	unsigned char optstr[128];	uint8_t *ptr8, *ptrarr8;	uint16_t *ptrarr16, data16;	uint32_t *ptrarr32, data32;	for (i = 0; s_option_list[i].code != 0; ++i)		if (s_option_list[i].code == code)			break;	// invalid option code	if (s_option_list[i].code == 0)		return;	// code 	optstr[DHCPOPT_CODE] = (unsigned char) code;	// copy data	len = s_option_len[s_option_list[i].flags & DHCPOPT_TYPEMASK];	copylen = 0;	// don't use pointer to uint16_t or uint32_t	// due to the alignment, pointer returns wrong value	ptr8 = (uint8_t *) (optstr + DHCPOPT_DATA);	switch (len) {	case 1 : 		if (list) {			ptrarr8 = (uint8_t *) data;			copylen = list * 1;			while (list-- > 0) 				*ptr8++ = *ptrarr8++;		} else {			copylen = 1;			*ptr8 = (uint8_t) data;		}		break;	case 2 :		if (list) {			ptrarr16 = (uint16_t *) data;			copylen = list * 2;			while (list-- > 0) {				data16 = htons(*ptrarr16++);				memcpy(ptr8, &data16, 2);				ptr8 += 2;			}		} else {			copylen = 2;			data16 = htons((uint16_t) data);			memcpy(ptr8, &data16, 2);			ptr8 += 2;		}		break;	case 4 :		if (list) {			ptrarr32 = (uint32_t *) data;			copylen = list * 4;			while (list-- > 0) {				data32 = htonl(*ptrarr32++);				memcpy(ptr8, &data32, 4);				ptr8 += 4;			}		} else {			copylen = 4;			data32 = htonl((uint32_t) data);			memcpy(ptr8, &data32, 4);			ptr8 += 4;		}		break;	case -1 : 		copylen = strlen((unsigned char *) data);		memcpy(optstr + DHCPOPT_DATA, (void *) data, copylen);		break;	case -2 : 		copylen = list;		memcpy(optstr + DHCPOPT_DATA, (void *) data, copylen);		break;	default :		// invalid length. 		break;	}	// option length	optstr[DHCPOPT_LEN] = copylen;	dhcp_option_appendstr(str, optstr);}void dhcp_parse_option(unsigned char *str, dhcp_info_t *info){	unsigned char *cp = str;	uint8_t *ptr8;	uint16_t data16;	uint32_t data32;	// look for the end of option	for (cp += 4; *cp != DHCP_END;) {		if (*cp == DHCP_PADDING) 			++cp;		else {			// don't use pointer to uint16_t or uint32_t			// due to the alignment, pointer returns wrong value			ptr8 = cp + DHCPOPT_DATA;			data16 = (ptr8[0] << 8) | (ptr8[1]);			data32 = (data16 << 16) | (ptr8[2] << 8) | (ptr8[3]);			switch (cp[DHCPOPT_CODE]) {			case DHCP_MESSAGE_TYPE :				info->message_type = *ptr8;				break;			case DHCP_SERVER_ID : 				info->server_id = data32;				break;			case DHCP_LEASE_TIME :				info->lease_time = data32;				break;			case DHCP_SUBNET :				info->subnet = data32;				break;			case DHCP_ROUTER :				info->router = data32;				break;			case DHCP_DNS_SERVER :				info->dns_server = data32;				break;			case DHCP_BROADCAST :				info->broadcast = data32;				break;			case DHCP_DOMAIN_NAME :				strncpy0(info->domain, ptr8, cp[DHCPOPT_LEN] + 1);				break;			}			cp += cp[DHCPOPT_LEN] + 2;		}	}}// show BOOTP packet contentsvoid bootp_dump_packet(struct sk_buff *skb, int need_parsing){	int i;	unsigned char *cp;	if (need_parsing)		bootp_parsepacket(skb);	PrintFormat("BOOTP : \n");	PrintFormat("  opcode : %02x (%s)\n", 		skb->bootp->bp_op, 		skb->bootp->bp_op == BOOTP_REQUEST ? "Request" : "Reply");	PrintFormat("  htype : %02x\n", skb->bootp->bp_htype);	PrintFormat("  hlen : %02x\n", skb->bootp->bp_hlen);	PrintFormat("  xid : %08x\n", skb->bootp->bp_xid);	PrintFormat("  secs : %04x\n", skb->bootp->bp_secs);	PrintFormat("  Client Address : %s (%08x)\n", 		ipaddr_to_str(skb->bootp->bp_ciaddr), skb->bootp->bp_ciaddr);	PrintFormat("  Your Address : %s (%08x)\n", 		ipaddr_to_str(skb->bootp->bp_yiaddr), skb->bootp->bp_yiaddr);	PrintFormat("  Server Address : %s (%08x)\n", 		ipaddr_to_str(skb->bootp->bp_siaddr), skb->bootp->bp_siaddr);	PrintFormat("  Gateway Address : %s (%08x)\n", 		ipaddr_to_str(skb->bootp->bp_giaddr), skb->bootp->bp_giaddr);	PrintFormat("  Hardware Address : %02X:%02X:%02X:%02X:%02X:%02X\n",		skb->bootp->bp_hwaddr[0], skb->bootp->bp_hwaddr[1], 		skb->bootp->bp_hwaddr[2], skb->bootp->bp_hwaddr[3], 		skb->bootp->bp_hwaddr[4], skb->bootp->bp_hwaddr[5]);	PrintFormat("  Options :\n");	for (cp = skb->bootp->bp_vend + 4; *cp != DHCP_END;) {		if (*cp == DHCP_PADDING) 			++cp;		else {			PrintFormat("    %02x, %02x : ", cp[0], cp[1]);			for (i = 2; i < cp[1] + 2; ++i)				PrintFormat("%02x ", cp[i]);			PrintFormat("\n");			cp += cp[DHCPOPT_LEN] + 2;		}	}}

⌨️ 快捷键说明

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