Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / clients / net-snk / app / netlib / udp.c
1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12
13 /*>>>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<*/
14
15 #include <udp.h>
16 #include <sys/socket.h>
17 #include <dhcp.h>
18 #include <dhcpv6.h>
19 #include <dns.h>
20 #ifdef USE_MTFTP
21 #include <mtftp.h>
22 #else
23 #include <tftp.h>
24 #endif
25
26
27
28 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<*/
29
30
31 #ifdef USE_MTFTP
32
33 uint16_t net_tftp_uport;
34 uint16_t net_mtftp_uport;
35
36 void net_set_tftp_port(uint16_t tftp_port) {
37         net_tftp_uport = tftp_port;
38 }
39
40 void net_set_mtftp_port(uint16_t tftp_port) {
41         net_mtftp_uport = tftp_port;
42 }
43
44 #endif
45
46 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<*/
47
48
49 /**
50  * NET: Handles UDP-packets according to Receive-handle diagram.
51  *
52  * @param  udp_packet UDP-packet to be handled
53  * @param  packetsize Length of the packet
54  * @return            ZERO - packet handled successfully;
55  *                    NON ZERO - packet was not handled (e.g. bad format)
56  * @see               receive_ether
57  * @see               udphdr
58  */
59 int8_t
60 handle_udp(int fd, uint8_t * udp_packet, int32_t packetsize) {
61         struct udphdr * udph = (struct udphdr *) udp_packet;
62
63         if (packetsize < sizeof(struct udphdr))
64                 return -1; // packet is too small
65
66         switch (htons(udph -> uh_dport)) {
67         case UDPPORT_BOOTPC:
68                 if (udph -> uh_sport == htons(UDPPORT_BOOTPS))
69                         return handle_dhcp(fd, udp_packet + sizeof(struct udphdr),
70                                             packetsize - sizeof(struct udphdr));
71                 else
72                         return -1;
73         case UDPPORT_DNSC:
74                 if (udph -> uh_sport == htons(UDPPORT_DNSS))
75                         return handle_dns(udp_packet + sizeof(struct udphdr),
76                                           packetsize - sizeof(struct udphdr));
77                 else
78                         return -1;
79         case UDPPORT_DHCPV6C:
80                 return handle_dhcpv6(udp_packet+sizeof(struct udphdr),
81                                      packetsize - sizeof(struct udphdr));
82         case UDPPORT_TFTPC:
83 #ifdef USE_MTFTP
84                 return handle_tftp(fd, udp_packet + sizeof(struct udphdr),
85                                        packetsize - sizeof(struct udphdr));
86 #else
87                 return handle_tftp(fd, udp_packet, packetsize);
88 #endif
89         default:
90 #ifdef USE_MTFTP
91                 if (htons(udph -> uh_dport) == net_tftp_uport)
92                         return handle_tftp(fd, udp_packet + sizeof(struct udphdr),
93                        packetsize - sizeof(struct udphdr));
94                 else if (htons(udph -> uh_dport) == net_mtftp_uport)
95                         return handle_tftp(fd, udp_packet + sizeof(struct udphdr),
96                        packetsize - sizeof(struct udphdr));
97 #endif
98                 return -1;
99         }
100 }
101
102 /**
103  * NET: This function handles situation when "Destination unreachable"
104  *      ICMP-error occurs during sending UDP-packet.
105  *
106  * @param  err_code   Error Code (e.g. "Host unreachable")
107  * @param  packet     original UDP-packet
108  * @param  packetsize length of the packet
109  * @see               handle_icmp
110  */
111 void
112 handle_udp_dun(uint8_t * udp_packet, uint32_t packetsize, uint8_t err_code) {
113         struct udphdr * udph = (struct udphdr *) udp_packet;
114
115         if (packetsize < sizeof(struct udphdr))
116                 return; // packet is too small
117
118         switch (htons(udph -> uh_sport)) {
119         case UDPPORT_TFTPC:
120                 handle_tftp_dun(err_code);
121                 break;
122         }
123 }
124
125 /**
126  * NET: Creates UDP-packet. Places UDP-header in a packet and fills it
127  *      with corresponding information.
128  *      <p>
129  *      Use this function with similar functions for other network layers
130  *      (fill_ethhdr, fill_iphdr, fill_dnshdr, fill_btphdr).
131  *
132  * @param  packet      Points to the place where UDP-header must be placed.
133  * @param  packetsize  Size of the packet in bytes incl. this hdr and data.
134  * @param  src_port    UDP source port
135  * @param  dest_port   UDP destination port
136  * @see                udphdr
137  * @see                fill_ethhdr
138  * @see                fill_iphdr
139  * @see                fill_dnshdr
140  * @see                fill_btphdr
141  */
142 void
143 fill_udphdr(uint8_t * packet, uint16_t packetsize,
144             uint16_t src_port, uint16_t dest_port) {
145         struct udphdr * udph = (struct udphdr *) packet;
146
147         udph -> uh_sport = htons(src_port);
148         udph -> uh_dport = htons(dest_port);
149         udph -> uh_ulen = htons(packetsize);
150         udph -> uh_sum = htons(0);
151 }