summaryrefslogtreecommitdiffstats
path: root/src/roms/SLOF/clients/net-snk/app/netlib/udp.c
blob: db29bc90f02181f8ab856ee0ad9943dac25d5a5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/******************************************************************************
 * Copyright (c) 2004, 2008 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/

/*>>>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<*/

#include <udp.h>
#include <sys/socket.h>
#include <dhcp.h>
#include <dhcpv6.h>
#include <dns.h>
#ifdef USE_MTFTP
#include <mtftp.h>
#else
#include <tftp.h>
#endif



/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<*/


#ifdef USE_MTFTP

uint16_t net_tftp_uport;
uint16_t net_mtftp_uport;

void net_set_tftp_port(uint16_t tftp_port) {
	net_tftp_uport = tftp_port;
}

void net_set_mtftp_port(uint16_t tftp_port) {
	net_mtftp_uport = tftp_port;
}

#endif

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<*/


/**
 * NET: Handles UDP-packets according to Receive-handle diagram.
 *
 * @param  udp_packet UDP-packet to be handled
 * @param  packetsize Length of the packet
 * @return            ZERO - packet handled successfully;
 *                    NON ZERO - packet was not handled (e.g. bad format)
 * @see               receive_ether
 * @see               udphdr
 */
int8_t
handle_udp(int fd, uint8_t * udp_packet, int32_t packetsize) {
	struct udphdr * udph = (struct udphdr *) udp_packet;

	if (packetsize < sizeof(struct udphdr))
		return -1; // packet is too small

	switch (htons(udph -> uh_dport)) {
	case UDPPORT_BOOTPC:
		if (udph -> uh_sport == htons(UDPPORT_BOOTPS))
			return handle_dhcp(fd, udp_packet + sizeof(struct udphdr),
			                    packetsize - sizeof(struct udphdr));
		else
			return -1;
	case UDPPORT_DNSC:
		if (udph -> uh_sport == htons(UDPPORT_DNSS))
			return handle_dns(udp_packet + sizeof(struct udphdr),
			                  packetsize - sizeof(struct udphdr));
		else
			return -1;
        case UDPPORT_DHCPV6C:
                return handle_dhcpv6(udp_packet+sizeof(struct udphdr),
                                     packetsize - sizeof(struct udphdr));
	case UDPPORT_TFTPC:
#ifdef USE_MTFTP
		return handle_tftp(fd, udp_packet + sizeof(struct udphdr),
			               packetsize - sizeof(struct udphdr));
#else
		return handle_tftp(fd, udp_packet, packetsize);
#endif
	default:
#ifdef USE_MTFTP
		if (htons(udph -> uh_dport) == net_tftp_uport)
			return handle_tftp(fd, udp_packet + sizeof(struct udphdr),
                       packetsize - sizeof(struct udphdr));
		else if (htons(udph -> uh_dport) == net_mtftp_uport)
			return handle_tftp(fd, udp_packet + sizeof(struct udphdr),
                       packetsize - sizeof(struct udphdr));
#endif
		return -1;
	}
}

/**
 * NET: This function handles situation when "Destination unreachable"
 *      ICMP-error occurs during sending UDP-packet.
 *
 * @param  err_code   Error Code (e.g. "Host unreachable")
 * @param  packet     original UDP-packet
 * @param  packetsize length of the packet
 * @see               handle_icmp
 */
void
handle_udp_dun(uint8_t * udp_packet, uint32_t packetsize, uint8_t err_code) {
	struct udphdr * udph = (struct udphdr *) udp_packet;

	if (packetsize < sizeof(struct udphdr))
		return; // packet is too small

	switch (htons(udph -> uh_sport)) {
	case UDPPORT_TFTPC:
		handle_tftp_dun(err_code);
		break;
	}
}

/**
 * NET: Creates UDP-packet. Places UDP-header in a packet and fills it
 *      with corresponding information.
 *      <p>
 *      Use this function with similar functions for other network layers
 *      (fill_ethhdr, fill_iphdr, fill_dnshdr, fill_btphdr).
 *
 * @param  packet      Points to the place where UDP-header must be placed.
 * @param  packetsize  Size of the packet in bytes incl. this hdr and data.
 * @param  src_port    UDP source port
 * @param  dest_port   UDP destination port
 * @see                udphdr
 * @see                fill_ethhdr
 * @see                fill_iphdr
 * @see                fill_dnshdr
 * @see                fill_btphdr
 */
void
fill_udphdr(uint8_t * packet, uint16_t packetsize,
            uint16_t src_port, uint16_t dest_port) {
	struct udphdr * udph = (struct udphdr *) packet;

	udph -> uh_sport = htons(src_port);
	udph -> uh_dport = htons(dest_port);
	udph -> uh_ulen = htons(packetsize);
	udph -> uh_sum = htons(0);
}
OpenPOWER on IntegriCloud