source: mainline/uspace/srv/net/tl/tl_common.c@ c92a5753

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c92a5753 was 21580dd, checked in by Lukas Mejdrech <lukas@…>, 15 years ago

Merged with network branch svn://svn.helenos.org/HelenOS/branches/network revision 4759; ipc_share_* and ipc_data_* changed to async_*; client connection in module.c returns on IPC_M_PHONE_HUNGUP; * Qemu scripts renamed to net-qe.*; (the dp8390 does not respond)

  • Property mode set to 100644
File size: 6.0 KB
RevLine 
[21580dd]1/*
2 * Copyright (c) 2008 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup net_tl
30 * @{
31 */
32
33/** @file
34 * Transport layer common functions implementation.
35 * @see tl_common.h
36 */
37
38#include <async.h>
39#include <ipc/services.h>
40
41#include "../err.h"
42
43#include "../structures/packet/packet.h"
44#include "../structures/packet/packet_client.h"
45
46#include "../include/icmp_interface.h"
47#include "../include/in.h"
48#include "../include/in6.h"
49#include "../include/inet.h"
50#include "../include/ip_interface.h"
51#include "../include/socket_codes.h"
52#include "../include/socket_errno.h"
53
54#include "tl_common.h"
55
56DEVICE_MAP_IMPLEMENT( packet_dimensions, packet_dimension_t );
57
58int tl_get_address_port( const struct sockaddr * addr, int addrlen, uint16_t * port ){
59 const struct sockaddr_in * address_in;
60 const struct sockaddr_in6 * address_in6;
61
62 if(( addrlen <= 0 ) || (( size_t ) addrlen < sizeof( struct sockaddr ))) return EINVAL;
63 switch( addr->sa_family ){
64 case AF_INET:
65 if( addrlen != sizeof( struct sockaddr_in )) return EINVAL;
66 address_in = ( struct sockaddr_in * ) addr;
67 * port = ntohs( address_in->sin_port );
68 break;
69 case AF_INET6:
70 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
71 address_in6 = ( struct sockaddr_in6 * ) addr;
72 * port = ntohs( address_in6->sin6_port );
73 break;
74 default:
75 return EAFNOSUPPORT;
76 }
77 return EOK;
78}
79
80int tl_get_ip_packet_dimension( int ip_phone, packet_dimensions_ref packet_dimensions, device_id_t device_id, packet_dimension_ref * packet_dimension ){
81 ERROR_DECLARE;
82
83 if( ! packet_dimension ) return EBADMEM;
84
85 * packet_dimension = packet_dimensions_find( packet_dimensions, device_id );
86 if( ! * packet_dimension ){
87 // ask for and remember them if not found
88 * packet_dimension = malloc( sizeof( ** packet_dimension ));
89 if( ! * packet_dimension ) return ENOMEM;
90 if( ERROR_OCCURRED( ip_packet_size_req( ip_phone, device_id, & ( ** packet_dimension ).addr_len, & ( ** packet_dimension ).prefix, & ( ** packet_dimension ).content, & ( ** packet_dimension ).suffix ))){
91 free( * packet_dimension );
92 return ERROR_CODE;
93 }
94 ERROR_CODE = packet_dimensions_add( packet_dimensions, device_id, * packet_dimension );
95 if( ERROR_CODE < 0 ){
96 free( * packet_dimension );
97 return ERROR_CODE;
98 }
99 }
100 return EOK;
101}
102
103int tl_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port ){
104 struct sockaddr_in * address_in;
105 struct sockaddr_in6 * address_in6;
106 size_t length;
107
108 if( addrlen < 0 ) return EINVAL;
109 length = ( size_t ) addrlen;
110 if( length < sizeof( struct sockaddr )) return EINVAL;
111 switch( addr->sa_family ){
112 case AF_INET:
113 if( length != sizeof( struct sockaddr_in )) return EINVAL;
114 address_in = ( struct sockaddr_in * ) addr;
115 address_in->sin_port = htons( port );
116 return EOK;
117 case AF_INET6:
118 if( length != sizeof( struct sockaddr_in6 )) return EINVAL;
119 address_in6 = ( struct sockaddr_in6 * ) addr;
120 address_in6->sin6_port = htons( port );
121 return EOK;
122 default:
123 return EAFNOSUPPORT;
124 }
125}
126
127int tl_prepare_icmp_packet( int packet_phone, int icmp_phone, packet_t packet, services_t error ){
128 packet_t next;
129 uint8_t * src;
130 int length;
131
132 // detach the first packet and release the others
133 next = pq_detach( packet );
134 if( next ){
135 pq_release( packet_phone, packet_get_id( next ));
136 }
137 length = packet_get_addr( packet, & src, NULL );
138 if(( length > 0 )
139 && ( ! error )
140 && ( icmp_phone >= 0 )
141 // set both addresses to the source one (avoids the source address deletion before setting the destination one)
142 && ( packet_set_addr( packet, src, src, ( size_t ) length ) == EOK )){
143 return EOK;
144 }else{
145 pq_release( packet_phone, packet_get_id( packet ));
146 }
147 return ENOENT;
148}
149
150int tl_socket_read_packet_data( int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen ){
151 ERROR_DECLARE;
152
153 ipc_callid_t callid;
154 size_t length;
155 void * data;
156
157 if( ! dimension ) return EINVAL;
158 // get the data length
159 if( ! async_data_write_receive( & callid, & length )) return EINVAL;
160 // get a new packet
161 * packet = packet_get_4( packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix );
162 if( ! packet ) return ENOMEM;
163 // allocate space in the packet
164 data = packet_suffix( * packet, length );
165 if( ! data ){
166 pq_release( packet_phone, packet_get_id( * packet ));
167 return ENOMEM;
168 }
169 // read the data into the packet
170 if( ERROR_OCCURRED( async_data_write_finalize( callid, data, length ))
171 // set the packet destination address
172 || ERROR_OCCURRED( packet_set_addr( * packet, NULL, ( uint8_t * ) addr, addrlen ))){
173 pq_release( packet_phone, packet_get_id( * packet ));
174 return ERROR_CODE;
175 }
176 return ( int ) length;
177}
178
179/** @}
180 */
Note: See TracBrowser for help on using the repository browser.