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
|
/******************************************************************************
* 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>
#include <tftp.h>
/****************************** 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, uint32_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:
return handle_tftp(fd, udp_packet, packetsize);
default:
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);
}
|