1 /** @file
2 Raw IP4 transmit application
3
4 Copyright (c) 2011-2012, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "RawIp4Tx.h"
16
17 UINT8 mBuffer[1024];
18
19 /**
20 Transmit raw IP4 packets to the remote system.
21
22 @param [in] ArgC Argument count
23 @param [in] ArgV Argument value array
24
25 @retval 0 Successfully operation
26 **/
27
28 int
RawIp4Tx(IN int ArgC,IN char ** ArgV)29 RawIp4Tx (
30 IN int ArgC,
31 IN char **ArgV
32 )
33 {
34 UINT32 BytesSent;
35 ssize_t BytesTransmitted;
36 struct sockaddr_in LocalPort;
37 UINT32 RemoteAddress[4];
38 struct sockaddr_in RemotePort;
39 int RetVal;
40 UINT32 TotalSent;
41 SOCKET s;
42
43 //
44 // Create the socket
45 //
46 s = socket ( AF_INET, SOCK_RAW, RAW_PROTOCOL );
47 if ( -1 == s ) {
48 RetVal = GET_ERRNO;
49 printf ( "ERROR - socket error, errno: %d\r\n", RetVal );
50 }
51 else {
52 //
53 // Use for/break; instead of goto
54 //
55 for ( ; ; ) {
56 //
57 // Validate the arguments
58 //
59 if (( 2 > ArgC )
60 || ( 4 != sscanf ( ArgV[1],
61 "%d.%d.%d.%d",
62 &RemoteAddress[0],
63 &RemoteAddress[1],
64 &RemoteAddress[2],
65 &RemoteAddress[3]))
66 || ( 224 < RemoteAddress[0])
67 || ( 255 < RemoteAddress[1])
68 || ( 255 < RemoteAddress[2])
69 || ( 255 < RemoteAddress[3])
70 || (( 0 == RemoteAddress[0])
71 && ( 0 == RemoteAddress[1])
72 && ( 0 == RemoteAddress[2])
73 && ( 0 == RemoteAddress[3]))) {
74 printf ( "%s <remote IP address>\r\n", ArgV[0]);
75 RetVal = EINVAL;
76 break;
77 }
78
79 //
80 // Bind the socket to a local port
81 //
82 memset ( &LocalPort, 0, sizeof ( LocalPort ));
83 SIN_LEN ( LocalPort ) = sizeof ( LocalPort );
84 SIN_FAMILY ( LocalPort ) = AF_INET;
85 SIN_ADDR ( LocalPort ) = 0;
86 SIN_PORT ( LocalPort ) = 0;
87 RetVal = bind ( s,
88 (struct sockaddr *)&LocalPort,
89 sizeof ( LocalPort ));
90 if ( -1 == RetVal ) {
91 RetVal = GET_ERRNO;
92 printf ( "ERROR - bind error, errno: %d\r\n", RetVal );
93 break;
94 }
95
96 //
97 // Specify the remote port
98 //
99 memset ( &RemotePort, 0, sizeof ( RemotePort ));
100 SIN_LEN ( RemotePort ) = sizeof ( RemotePort );
101 SIN_FAMILY ( RemotePort ) = AF_INET;
102 SIN_ADDR ( RemotePort ) = ( RemoteAddress[3] << 24 )
103 | ( RemoteAddress[2] << 16 )
104 | ( RemoteAddress[1] << 8 )
105 | RemoteAddress[0];
106 SIN_PORT ( RemotePort ) = 0;
107
108 //
109 // Initialize the messages
110 //
111 memset ( &mBuffer[0], 0, sizeof ( mBuffer ));
112
113 //
114 // Send the data before the out-of-band message
115 //
116 TotalSent = 0;
117 BytesSent = 0;
118 do {
119 BytesTransmitted = sendto ( s,
120 &mBuffer[BytesSent],
121 sizeof ( mBuffer ) - BytesSent,
122 0,
123 (struct sockaddr *)&RemotePort,
124 sizeof ( RemotePort ));
125 if ( -1 == BytesTransmitted ) {
126 RetVal = GET_ERRNO;
127 printf ( "ERROR - send before error, errno: %d\r\n", RetVal );
128 break;
129 }
130 BytesSent += (UINT32)BytesTransmitted;
131 RetVal = 0;
132 } while ( sizeof ( mBuffer ) > BytesSent );
133 if ( 0 != RetVal ) {
134 break;
135 }
136 TotalSent += BytesSent;
137
138 //
139 // Test completed successfully
140 //
141 if ( 0 == RetVal ) {
142 printf ( "Bytes sent: %8d\r\n", TotalSent );
143 }
144 break;
145 }
146
147 //
148 // Close the socket
149 //
150 CLOSE_SOCKET ( s );
151 }
152
153 //
154 // Return the operation status
155 //
156 return RetVal;
157 }
158