From 4b11c9166b86ccc5f8f02fda01ded0f9e9760df0 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 23 May 2012 07:59:07 +0000 Subject: net: Refactor IP, UPD, and ICMP header writing functions ICMP (ping) was reimplementing IP header code... it now shares code. Signed-off-by: Joe Hershberger Acked-by: Simon Glass Acked-by: Mike Frysinger diff --git a/include/net.h b/include/net.h index 3bf0806..128c5ea 100644 --- a/include/net.h +++ b/include/net.h @@ -457,7 +457,9 @@ extern int NetEthHdrSize(void); extern int NetSetEther(uchar *, uchar *, uint); /* Set IP header */ -extern void NetSetIP(uchar *, IPaddr_t, int, int, int); +extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source); +extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, + int sport, int len); /* Checksum */ extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ diff --git a/net/bootp.c b/net/bootp.c index 009369b..7346993 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -619,9 +619,9 @@ BootpRequest(void) * determined. * C. Hallinan, DS4.COM, Inc. */ - /* NetSetIP(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, + /* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, sizeof (struct Bootp_t)); */ - iphdr = pkt; /* We need this later for NetSetIP() */ + iphdr = pkt; /* We need this later for net_set_udp_header() */ pkt += IP_UDP_HDR_SIZE; bp = (struct Bootp_t *)pkt; @@ -663,7 +663,7 @@ BootpRequest(void) pktlen = ((int)(pkt-NetTxPacket)) + BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len; iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len; - NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); + net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); NetSetTimeout(SELECT_TIMEOUT, BootpTimeout); #if defined(CONFIG_CMD_DHCP) @@ -844,7 +844,7 @@ static void DhcpSendRequestPkt(struct Bootp_t *bp_offer) pktlen = ((int)(pkt-NetTxPacket)) + BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen; iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen; - NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); + net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen); #ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY diff --git a/net/net.c b/net/net.c index de5352c..1c7bf60 100644 --- a/net/net.c +++ b/net/net.c @@ -618,7 +618,7 @@ int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, pkt = NetArpWaitTxPacket; pkt += NetSetEther(pkt, NetArpWaitPacketMAC, PROT_IP); - NetSetIP(pkt, dest, dport, sport, payload_len); + net_set_udp_header(pkt, dest, dport, sport, payload_len); memcpy(pkt + IP_UDP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_UDP_HDR_SIZE, payload_len); @@ -638,7 +638,7 @@ int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, pkt = (uchar *)NetTxPacket; pkt += NetSetEther(pkt, ether, PROT_IP); - NetSetIP(pkt, dest, dport, sport, payload_len); + net_set_udp_header(pkt, dest, dport, sport, payload_len); eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_UDP_HDR_SIZE + payload_len); @@ -1245,40 +1245,49 @@ NetSetEther(uchar *xet, uchar * addr, uint prot) } } -void NetSetIP(uchar *xip, IPaddr_t dest, int dport, int sport, int len) +void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source) { - struct ip_udp_hdr *ip = (struct ip_udp_hdr *)xip; + struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt; /* - * If the data is an odd number of bytes, zero the - * byte after the last byte so that the checksum - * will work. - */ - if (len & 1) - xip[IP_UDP_HDR_SIZE + len] = 0; - - /* - * Construct an IP and UDP header. - * (need to set no fragment bit - XXX) + * Construct an IP header. */ /* IP_HDR_SIZE / 4 (not including UDP) */ ip->ip_hl_v = 0x45; ip->ip_tos = 0; - ip->ip_len = htons(IP_UDP_HDR_SIZE + len); + ip->ip_len = htons(IP_HDR_SIZE); ip->ip_id = htons(NetIPID++); ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */ ip->ip_ttl = 255; - ip->ip_p = 17; /* UDP */ ip->ip_sum = 0; /* already in network byte order */ - NetCopyIP((void *)&ip->ip_src, &NetOurIP); - /* - "" - */ + NetCopyIP((void *)&ip->ip_src, &source); + /* already in network byte order */ NetCopyIP((void *)&ip->ip_dst, &dest); +} + +void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport, + int len) +{ + struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt; + + /* + * If the data is an odd number of bytes, zero the + * byte after the last byte so that the checksum + * will work. + */ + if (len & 1) + pkt[IP_UDP_HDR_SIZE + len] = 0; + + net_set_ip_header(pkt, dest, NetOurIP); + ip->ip_len = htons(IP_UDP_HDR_SIZE + len); + ip->ip_p = IPPROTO_UDP; + ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1); + ip->udp_src = htons(sport); ip->udp_dst = htons(dport); ip->udp_len = htons(UDP_HDR_SIZE + len); ip->udp_xsum = 0; - ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE / 2); } void copy_filename(char *dst, const char *src, int size) diff --git a/net/ping.c b/net/ping.c index 3102521..c525635 100644 --- a/net/ping.c +++ b/net/ping.c @@ -16,11 +16,31 @@ static ushort PingSeqNo; /* The ip address to ping */ IPaddr_t NetPingIP; +static void set_icmp_header(uchar *pkt, IPaddr_t dest) +{ + /* + * Construct an IP and ICMP header. + */ + struct ip_hdr *ip = (struct ip_hdr *)pkt; + struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE); + + net_set_ip_header(pkt, dest, NetOurIP); + + ip->ip_len = htons(IP_ICMP_HDR_SIZE); + ip->ip_p = IPPROTO_ICMP; + ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1); + + icmp->type = ICMP_ECHO_REQUEST; + icmp->code = 0; + icmp->checksum = 0; + icmp->un.echo.id = 0; + icmp->un.echo.sequence = htons(PingSeqNo++); + icmp->checksum = ~NetCksum((uchar *)icmp, ICMP_HDR_SIZE >> 1); +} + static int ping_send(void) { static uchar mac[6]; - struct ip_udp_hdr *ip; - ushort *s; uchar *pkt; /* XXX always send arp request */ @@ -35,33 +55,7 @@ static int ping_send(void) pkt = NetArpWaitTxPacket; pkt += NetSetEther(pkt, mac, PROT_IP); - ip = (struct ip_udp_hdr *)pkt; - - /* - * Construct an IP and ICMP header. - * (need to set no fragment bit - XXX) - */ - /* IP_HDR_SIZE / 4 (not including UDP) */ - ip->ip_hl_v = 0x45; - ip->ip_tos = 0; - ip->ip_len = htons(IP_HDR_SIZE + 8); - ip->ip_id = htons(NetIPID++); - ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */ - ip->ip_ttl = 255; - ip->ip_p = 0x01; /* ICMP */ - ip->ip_sum = 0; - /* already in network byte order */ - NetCopyIP((void *)&ip->ip_src, &NetOurIP); - /* - "" - */ - NetCopyIP((void *)&ip->ip_dst, &NetPingIP); - ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE / 2); - - s = &ip->udp_src; /* XXX ICMP starts here */ - s[0] = htons(0x0800); /* echo-request, code */ - s[1] = 0; /* checksum */ - s[2] = 0; /* identifier */ - s[3] = htons(PingSeqNo++); /* sequence number */ - s[1] = ~NetCksum((uchar *)s, 8/2); + set_icmp_header(pkt, NetPingIP); /* size of the waiting packet */ NetArpWaitTxPacketSize = -- cgit v0.10.2