Browse Source

In multicast operation, the client still has a unicast local port.

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
7d8adc25bc
3 changed files with 103 additions and 95 deletions
  1. 9
    10
      src/include/tftp.h
  2. 5
    5
      src/proto/tftm.c
  3. 89
    80
      src/proto/tftpcore.c

+ 9
- 10
src/include/tftp.h View File

100
 	 * will be sent, and to which ACK packets should be sent.
100
 	 * will be sent, and to which ACK packets should be sent.
101
 	 */
101
 	 */
102
 	struct sockaddr_in server;
102
 	struct sockaddr_in server;
103
-	/** TFTP client address
103
+	/** TFTP client port
104
 	 *
104
 	 *
105
-	 * The IP address, if any, is the multicast address to which
106
-	 * data packets will be sent.  The client will always send
107
-	 * packets from its own IP address.
105
+	 * This is the UDP port from which the open request will be
106
+	 * sent, and to which any unicast data packets will be sent.
107
+	 */
108
+	in_port_t lport;
109
+	/** TFTP multicast address
108
 	 *
110
 	 *
109
-	 * The UDP port is the port from which the open request will
110
-	 * be sent, and to which data packets will be sent.  (Due to
111
-	 * the "design" of the MTFTP protocol, the master client will
112
-	 * receive its first data packet as unicast, and subsequent
113
-	 * packets as multicast.)
111
+	 * This is the IP address and UDP port to which multicast data
112
+	 * packets, if any, will be sent.
114
 	 */
113
 	 */
115
-	struct sockaddr_in client;
114
+	struct sockaddr_in multicast;
116
 	/** Master client
115
 	/** Master client
117
 	 *
116
 	 *
118
 	 * This will be true if the client is the master client for a
117
 	 * This will be true if the client is the master client for a

+ 5
- 5
src/proto/tftm.c View File

14
 
14
 
15
 static inline int tftm_process_opts ( struct tftp_state *state,
15
 static inline int tftm_process_opts ( struct tftp_state *state,
16
 				      struct tftp_oack *oack ) {
16
 				      struct tftp_oack *oack ) {
17
-	struct in_addr old_mcast_addr = state->client.sin_addr;
17
+	struct in_addr old_mcast_addr = state->multicast.sin_addr;
18
 
18
 
19
 	if ( ! tftp_process_opts ( state, oack ) )
19
 	if ( ! tftp_process_opts ( state, oack ) )
20
 		return 0;
20
 		return 0;
21
 
21
 
22
-	if ( old_mcast_addr.s_addr != state->client.sin_addr.s_addr ) {
22
+	if ( old_mcast_addr.s_addr != state->multicast.sin_addr.s_addr ) {
23
 		if ( old_mcast_addr.s_addr ) {
23
 		if ( old_mcast_addr.s_addr ) {
24
 			DBG ( "TFTM: Leaving multicast group %@\n",
24
 			DBG ( "TFTM: Leaving multicast group %@\n",
25
 			      old_mcast_addr.s_addr );
25
 			      old_mcast_addr.s_addr );
26
 			leave_group ( IGMP_SERVER );
26
 			leave_group ( IGMP_SERVER );
27
 		}
27
 		}
28
 		DBG ( "TFTM: Joining multicast group %@\n",
28
 		DBG ( "TFTM: Joining multicast group %@\n",
29
-		      state->client.sin_addr.s_addr );
30
-		join_group ( IGMP_SERVER, state->client.sin_addr.s_addr );
29
+		      state->multicast.sin_addr.s_addr );
30
+		join_group ( IGMP_SERVER, state->multicast.sin_addr.s_addr );
31
 	}
31
 	}
32
 
32
 
33
 	DBG ( "TFTM: I am a %s client\n",
33
 	DBG ( "TFTM: I am a %s client\n",
195
 
195
 
196
 	rc = 1;
196
 	rc = 1;
197
  out:
197
  out:
198
-	if ( state.client.sin_addr.s_addr ) {
198
+	if ( state.multicast.sin_addr.s_addr ) {
199
 		leave_group ( IGMP_SERVER );
199
 		leave_group ( IGMP_SERVER );
200
 	}
200
 	}
201
 	return rc;
201
 	return rc;

+ 89
- 80
src/proto/tftpcore.c View File

9
 /**
9
 /**
10
  * await_reply() filter for TFTP packets
10
  * await_reply() filter for TFTP packets
11
  *
11
  *
12
- * @v ptr			Pointer to a struct tftp_state
13
- * @v tftp_state::server::sin_addr TFTP server IP address
14
- * @v tftp_state::client::sin_addr Client multicast IP address, or 0.0.0.0
15
- * @v tftp_state::client::sin_port Client UDP port
16
- * @v ip			IP header
17
- * @v udp			UDP header
18
- * @ret True			This is our TFTP packet
19
- * @ret False			This is not one of our TFTP packets
12
+ * @v ptr				Pointer to a struct tftp_state
13
+ * @v tftp_state::server::sin_addr	TFTP server IP address
14
+ * @v tftp_state::lport			Client UDP port
15
+ * @v tftp_state::multicast::sin_addr	Multicast IP address, or 0.0.0.0
16
+ * @v tftp_state::multicast::sin_port	Multicast UDP port, or 0
17
+ * @v ip				IP header
18
+ * @v udp				UDP header
19
+ * @ret True				This is our TFTP packet
20
+ * @ret False				This is not one of our TFTP packets
20
  *
21
  *
21
  * Wait for a TFTP packet that is part of the current connection
22
  * Wait for a TFTP packet that is part of the current connection
22
  * (i.e. comes from the TFTP server, has the correct destination port,
23
  * (i.e. comes from the TFTP server, has the correct destination port,
23
- * and is addressed either to our IP address or to our multicast
24
- * listening address).
24
+ * and is addressed either to our IP address and UDP port, or to our
25
+ * multicast listening address and UDP port).
25
  *
26
  *
26
  * Use await_tftp() in code such as
27
  * Use await_tftp() in code such as
27
  *
28
  *
49
 		       ip->src.s_addr, state->server.sin_addr.s_addr );
50
 		       ip->src.s_addr, state->server.sin_addr.s_addr );
50
 		return 0;
51
 		return 0;
51
 	}
52
 	}
52
-	/* Packet must be addressed to the correct UDP port */
53
-	if ( ntohs ( udp->dest ) != state->client.sin_port ) {
54
-		DBG2 ( "TFTPCORE: to UDP port %d, not to TFTP port %d\n",
55
-		       ntohs ( udp->dest ), state->client.sin_port );
56
-		return 0;
53
+	/* Packet may be addressed to our IP address and unicast UDP
54
+	 * port
55
+	 */
56
+	if ( ( ip->dest.s_addr == arptable[ARP_CLIENT].ipaddr.s_addr ) &&
57
+	     ( ntohs ( udp->dest ) == state->lport ) ) {
58
+		return 1;
57
 	}
59
 	}
58
-	/* Packet must be addressed to us, or to our multicast
59
-	 * listening address (if we have one).
60
+	/* Packet may be addressed to our multicast IP address and UDP
61
+	 * port, if we have one
60
 	 */
62
 	 */
61
-	if ( ! ( ( ip->dest.s_addr == arptable[ARP_CLIENT].ipaddr.s_addr ) ||
62
-		 ( ( state->client.sin_addr.s_addr ) && 
63
-		   ( ip->dest.s_addr == state->client.sin_addr.s_addr ) ) ) ) {
64
-		DBG2 ( "TFTPCORE: to %@, not to %@ (or %@)\n",
65
-		       ip->dest.s_addr, arptable[ARP_CLIENT].ipaddr.s_addr,
66
-		       state->client.sin_addr.s_addr );
67
-		return 0;
63
+	if ( ( state->multicast.sin_addr.s_addr ) && 
64
+	     ( ip->dest.s_addr == state->multicast.sin_addr.s_addr ) &&
65
+	     ( ntohs ( udp->dest ) == state->multicast.sin_port ) ) {
66
+		return 1;
68
 	}
67
 	}
69
-	return 1;
68
+	DBG2 ( "TFTPCORE: to %@:%d, not to %@:%d (or %@:%d)\n",
69
+	       ip->dest.s_addr, ntohs ( udp->dest ),
70
+	       arptable[ARP_CLIENT].ipaddr.s_addr, state->lport,
71
+	       state->multicast.sin_addr.s_addr, state->multicast.sin_port );
72
+	return 0;
70
 }
73
 }
71
 
74
 
72
 /**
75
 /**
73
  * Retrieve a TFTP packet
76
  * Retrieve a TFTP packet
74
  *
77
  *
75
- * @v state			TFTP transfer state
76
- * @v tftp_state::server::sin_addr TFTP server IP address
77
- * @v tftp_state::client::sin_addr Client multicast IP address, or 0.0.0.0
78
- * @v tftp_state::client::sin_port Client UDP port
79
- * @v timeout			Time to wait for a response
80
- * @ret True			Received a non-error response
81
- * @ret False			Received error response / no response
82
- * @ret *reply			The server's response, if any
83
- * @err #PXENV_STATUS_TFTP_READ_TIMEOUT No response received in time
84
- * @err other			As set by tftp_set_errno()
78
+ * @v state				TFTP transfer state
79
+ * @v tftp_state::server::sin_addr	TFTP server IP address
80
+ * @v tftp_state::lport			Client UDP port
81
+ * @v tftp_state::multicast::sin_addr	Multicast IP address, or 0.0.0.0
82
+ * @v tftp_state::multicast::sin_port	Multicast UDP port, or 0
83
+ * @v timeout				Time to wait for a response
84
+ * @ret True				Received a non-error response
85
+ * @ret False				Received error response / no response
86
+ * @ret *reply				The server's response, if any
87
+ * @err #PXENV_STATUS_TFTP_READ_TIMEOUT	No response received in time
88
+ * @err other				As set by tftp_set_errno()
85
  *
89
  *
86
  * Retrieve the next packet sent by the TFTP server, if any is sent
90
  * Retrieve the next packet sent by the TFTP server, if any is sent
87
  * within the specified timeout period.  The packet is returned via
91
  * within the specified timeout period.  The packet is returned via
121
  * @v state				TFTP transfer state
125
  * @v state				TFTP transfer state
122
  * @v tftp_state::server::sin_addr	TFTP server IP address
126
  * @v tftp_state::server::sin_addr	TFTP server IP address
123
  * @v tftp_state::server::sin_port	TFTP server UDP port, or 0
127
  * @v tftp_state::server::sin_port	TFTP server UDP port, or 0
124
- * @v tftp_state::client::sin_addr	Client multicast IP address, or 0.0.0.0
125
- * @v tftp_state::client::sin_port	Client UDP port, or 0
128
+ * @v tftp_state::lport			Client UDP port, or 0
129
+ * @v tftp_state::multicast::sin_addr	Multicast IP address, or 0.0.0.0
130
+ * @v tftp_state::multicast::sin_port	Multicast UDP port, or 0
126
  * @v tftp_state::blksize		Requested blksize, or 0
131
  * @v tftp_state::blksize		Requested blksize, or 0
127
  * @v filename				File name
132
  * @v filename				File name
128
  * @v multicast				Enable/disable rfc2090 multicast TFTP
133
  * @v multicast				Enable/disable rfc2090 multicast TFTP
129
  * @ret True				Received a non-error response
134
  * @ret True				Received a non-error response
130
  * @ret False				Received error response / no response
135
  * @ret False				Received error response / no response
131
  * @ret tftp_state::server::sin_port	TFTP server UDP port
136
  * @ret tftp_state::server::sin_port	TFTP server UDP port
132
- * @ret tftp_state::client::sin_port	Client UDP port
137
+ * @ret tftp_state::lport		Client UDP port
133
  * @ret tftp_state::blksize		Always #TFTP_DEFAULT_BLKSIZE
138
  * @ret tftp_state::blksize		Always #TFTP_DEFAULT_BLKSIZE
134
  * @ret *reply				The server's response, if any
139
  * @ret *reply				The server's response, if any
135
  * @err #PXENV_STATUS_TFTP_OPEN_TIMEOUT	TFTP open timed out
140
  * @err #PXENV_STATUS_TFTP_OPEN_TIMEOUT	TFTP open timed out
144
  * If tftp_state::server::sin_port is 0, the standard TFTP server port
149
  * If tftp_state::server::sin_port is 0, the standard TFTP server port
145
  * (#TFTP_PORT) will be used.
150
  * (#TFTP_PORT) will be used.
146
  *
151
  *
147
- * If tftp_state::client::sin_addr is not 0.0.0.0, it will be used as
148
- * a multicast listening address for replies from the TFTP server.
149
- *
150
- * If tftp_state::client::sin_port is 0, the standard mechanism of
152
+ * If tftp_state::lport is 0, the standard mechanism of
151
  * using a new, unique port number for each TFTP request will be used.
153
  * using a new, unique port number for each TFTP request will be used.
152
  * 
154
  * 
155
+ * If tftp_state::multicast::sin_addr is not 0.0.0.0, it (and
156
+ * tftp_state::multicast::sin_port) will be used as a multicast
157
+ * listening address for replies from the TFTP server.
158
+ *
153
  * For the various different types of TFTP server, you should treat
159
  * For the various different types of TFTP server, you should treat
154
- * tftp_state::client as follows:
155
- *
156
- *   - Standard TFTP server: set tftp_state::client::sin_addr to
157
- *     0.0.0.0 and tftp_state::client::sin_port to 0.  tftp_open()
158
- *     will set tftp_state::client::sin_port to the assigned local UDP
159
- *     port.
160
- *
161
- *   - TFTM server: set tftp_state::client::sin_addr to 0.0.0.0 and
162
- *     tftp_state::client::sin_port to 0.  tftp_open() will set
163
- *     tftp_state::client::sin_port to the assigned local UDP port.
164
- *     (Your call to tftp_process_opts() will then overwrite both
165
- *     tftp_state::client::sin_addr and tftp_state::client::sin_port
166
- *     with the values return in the OACK packet.)
167
- *
168
- *   - MTFTP server: set tftp_state::client::sin_addr to the client
169
- *     multicast address and tftp_state::client::sin_port to the
170
- *     client multicast port (both of which must be previously known,
171
- *     e.g. provided by a DHCP server).  tftp_open() will not alter
172
- *     these values.
160
+ * tftp_state::lport and tftp_state::multicast as follows:
161
+ *
162
+ *   - Standard TFTP server: set tftp_state::lport to 0,
163
+ *     tftp_state::multicast::sin_addr to 0.0.0.0 and
164
+ *     tftp_state::multicast::sin_port to 0.  tftp_open() will set
165
+ *     tftp_state::lport to the assigned local UDP port.
166
+ *
167
+ *   - TFTM server: set tftp_state::lport to 0,
168
+ *     tftp_state::multicast::sin_addr to 0.0.0.0 and
169
+ *     tftp_state::multicast::sin_port to 0.  tftp_open() will set
170
+ *     tftp_state::lport to the assigned local UDP port.  (Your call
171
+ *     to tftp_process_opts() will then overwrite both
172
+ *     tftp_state::multicast::sin_addr and
173
+ *     tftp_state::multicast::sin_port with the values specified in
174
+ *     the OACK packet.)
175
+ *
176
+ *   - MTFTP server: set tftp_state::multicast::sin_addr to the
177
+ *     multicast address and both tftp_state::lport and
178
+ *     tftp_state::multicast::sin_port to the multicast port (both of
179
+ *     which must be previously known, e.g. provided by a DHCP
180
+ *     server).  tftp_open() will not alter these values.
173
  *
181
  *
174
  * If tftp_state::blksize is 0, the maximum blocksize
182
  * If tftp_state::blksize is 0, the maximum blocksize
175
  * (#TFTP_MAX_BLKSIZE) will be requested.
183
  * (#TFTP_MAX_BLKSIZE) will be requested.
216
 		state->server.sin_port = TFTP_PORT;
224
 		state->server.sin_port = TFTP_PORT;
217
 
225
 
218
 	/* Determine whether or not to use lport */
226
 	/* Determine whether or not to use lport */
219
-	fixed_lport = state->client.sin_port;
227
+	fixed_lport = state->lport;
220
 
228
 
221
 	/* Set up RRQ */
229
 	/* Set up RRQ */
222
 	rrq.opcode = htons ( TFTP_RRQ );
230
 	rrq.opcode = htons ( TFTP_RRQ );
240
 
248
 
241
 		/* Set client UDP port, if not already fixed */
249
 		/* Set client UDP port, if not already fixed */
242
 		if ( ! fixed_lport )
250
 		if ( ! fixed_lport )
243
-			state->client.sin_port = ++lport;
251
+			state->lport = ++lport;
244
 		
252
 		
245
 		/* Send the RRQ */
253
 		/* Send the RRQ */
246
 		DBG ( "TFTPCORE: requesting %@:%d/%s from port %d\n",
254
 		DBG ( "TFTPCORE: requesting %@:%d/%s from port %d\n",
247
 		      state->server.sin_addr.s_addr, state->server.sin_port,
255
 		      state->server.sin_addr.s_addr, state->server.sin_port,
248
-		      rrq.data, state->client.sin_port );
256
+		      rrq.data, state->lport );
249
 		if ( ! udp_transmit ( state->server.sin_addr.s_addr,
257
 		if ( ! udp_transmit ( state->server.sin_addr.s_addr,
250
-				      state->client.sin_port,
251
-				      state->server.sin_port,
258
+				      state->lport, state->server.sin_port,
252
 				      rrqlen, &rrq ) )
259
 				      rrqlen, &rrq ) )
253
 			return 0;
260
 			return 0;
254
 		
261
 		
282
  * @ret False				Options were not processed successfully
289
  * @ret False				Options were not processed successfully
283
  * @ret tftp_state::blksize		Negotiated blksize
290
  * @ret tftp_state::blksize		Negotiated blksize
284
  * @ret tftp_state::tsize		File size (if known), or 0
291
  * @ret tftp_state::tsize		File size (if known), or 0
285
- * @ret tftp_state::client::sin_addr	Client multicast IP address, or 0.0.0.0
286
- * @ret tftp_state::client::sin_port	Client UDP port
292
+ * @ret tftp_state::multicast::sin_addr	Multicast IP address, or 0.0.0.0
293
+ * @ret tftp_state::multicast::sin_port	Multicast UDP port, or 0
287
  * @ret tftp_state::master		Client is master
294
  * @ret tftp_state::master		Client is master
288
  * @err EINVAL				An invalid option value was encountered
295
  * @err EINVAL				An invalid option value was encountered
289
  *
296
  *
338
 			p++;
345
 			p++;
339
 			DBG ( "TFTPCORE: got tsize %d\n", state->tsize );
346
 			DBG ( "TFTPCORE: got tsize %d\n", state->tsize );
340
 		} else if ( strcasecmp ( "multicast", p ) == 0 ) {
347
 		} else if ( strcasecmp ( "multicast", p ) == 0 ) {
348
+			p += 10;
341
 			char *e = strchr ( p, ',' );
349
 			char *e = strchr ( p, ',' );
342
 			if ( ( ! e ) || ( e >= end ) ) {
350
 			if ( ( ! e ) || ( e >= end ) ) {
343
 				DBG ( "TFTPCORE: malformed multicast field "
351
 				DBG ( "TFTPCORE: malformed multicast field "
345
 				return 0;
353
 				return 0;
346
 			}
354
 			}
347
 			/* IP address may be missing, in which case we
355
 			/* IP address may be missing, in which case we
348
-			 * should leave state->client.sin_addr
356
+			 * should leave state->multicast.sin_addr
349
 			 * unaltered.
357
 			 * unaltered.
350
 			 */
358
 			 */
351
 			if ( e != p ) {
359
 			if ( e != p ) {
352
 				int rc;
360
 				int rc;
353
 				*e = '\0';
361
 				*e = '\0';
354
-				rc = inet_aton ( p, &state->client.sin_addr );
362
+				rc = inet_aton ( p,
363
+						 &state->multicast.sin_addr );
355
 				*e = ',';
364
 				*e = ',';
356
 				if ( ! rc ) {
365
 				if ( ! rc ) {
357
 					DBG ( "TFTPCORE: malformed multicast "
366
 					DBG ( "TFTPCORE: malformed multicast "
362
 			p = e + 1;
371
 			p = e + 1;
363
 			/* UDP port may also be missing */
372
 			/* UDP port may also be missing */
364
 			if ( *p != ',' ) {
373
 			if ( *p != ',' ) {
365
-				state->client.sin_port = strtoul ( p, &p, 10 );
374
+				state->multicast.sin_port
375
+					= strtoul ( p, &p, 10 );
366
 				if ( *p != ',' ) {
376
 				if ( *p != ',' ) {
367
 					DBG ( "TFTPCORE: garbage \"%s\" "
377
 					DBG ( "TFTPCORE: garbage \"%s\" "
368
 					      "after multicast port\n", p );
378
 					      "after multicast port\n", p );
369
 					return 0;
379
 					return 0;
370
 				}
380
 				}
371
-			} else {
372
-				p++;
373
 			}
381
 			}
382
+			p++;
374
 			/* "Master Client" must always be present */
383
 			/* "Master Client" must always be present */
375
 			state->master = strtoul ( p, &p, 10 );
384
 			state->master = strtoul ( p, &p, 10 );
376
 			if ( *p ) {
385
 			if ( *p ) {
380
 			}
389
 			}
381
 			p++;
390
 			p++;
382
 			DBG ( "TFTPCORE: got multicast %@:%d (%s)\n",
391
 			DBG ( "TFTPCORE: got multicast %@:%d (%s)\n",
383
-			      state->client.sin_addr.s_addr,
384
-			      state->client.sin_port,
392
+			      state->multicast.sin_addr.s_addr,
393
+			      state->multicast.sin_port,
385
 			      ( state->master ? "master" : "not master" ) );
394
 			      ( state->master ? "master" : "not master" ) );
386
 		} else {
395
 		} else {
387
 			DBG ( "TFTPCORE: unknown option \"%s\"\n", p );
396
 			DBG ( "TFTPCORE: unknown option \"%s\"\n", p );
404
  * @v state				TFTP transfer state
413
  * @v state				TFTP transfer state
405
  * @v tftp_state::server::sin_addr	TFTP server IP address
414
  * @v tftp_state::server::sin_addr	TFTP server IP address
406
  * @v tftp_state::server::sin_port	TFTP server UDP port
415
  * @v tftp_state::server::sin_port	TFTP server UDP port
407
- * @v tftp_state::client::sin_port	Client UDP port
416
+ * @v tftp_state::lport			Client UDP port
408
  * @v tftp_state::block			Most recently received block number
417
  * @v tftp_state::block			Most recently received block number
409
  * @ret True				Acknowledgement packet was sent
418
  * @ret True				Acknowledgement packet was sent
410
  * @ret False				Acknowledgement packet was not sent
419
  * @ret False				Acknowledgement packet was not sent
422
 	ack.opcode = htons ( TFTP_ACK );
431
 	ack.opcode = htons ( TFTP_ACK );
423
 	ack.block = htons ( state->block );
432
 	ack.block = htons ( state->block );
424
 	return udp_transmit ( state->server.sin_addr.s_addr,
433
 	return udp_transmit ( state->server.sin_addr.s_addr,
425
-			      state->client.sin_port, state->server.sin_port,
434
+			      state->lport, state->server.sin_port,
426
 			      sizeof ( ack ), &ack );
435
 			      sizeof ( ack ), &ack );
427
 }
436
 }
428
 
437
 
432
  * @v state				TFTP transfer state
441
  * @v state				TFTP transfer state
433
  * @v tftp_state::server::sin_addr	TFTP server IP address
442
  * @v tftp_state::server::sin_addr	TFTP server IP address
434
  * @v tftp_state::server::sin_port	TFTP server UDP port
443
  * @v tftp_state::server::sin_port	TFTP server UDP port
435
- * @v tftp_state::client::sin_port	Client UDP port
444
+ * @v tftp_state::lport			Client UDP port
436
  * @v tftp_state::block			Most recently received block number
445
  * @v tftp_state::block			Most recently received block number
437
  * @ret True				Received a non-error response
446
  * @ret True				Received a non-error response
438
  * @ret False				Received error response / no response
447
  * @ret False				Received error response / no response
484
  * @v state				TFTP transfer state
493
  * @v state				TFTP transfer state
485
  * @v tftp_state::server::sin_addr	TFTP server IP address
494
  * @v tftp_state::server::sin_addr	TFTP server IP address
486
  * @v tftp_state::server::sin_port	TFTP server UDP port
495
  * @v tftp_state::server::sin_port	TFTP server UDP port
487
- * @v tftp_state::client::sin_port	Client UDP port
496
+ * @v tftp_state::lport			Client UDP port
488
  * @v errcode				TFTP error code
497
  * @v errcode				TFTP error code
489
  * @v errmsg				Descriptive error string, or NULL
498
  * @v errmsg				Descriptive error string, or NULL
490
  * @ret True				Error packet was sent
499
  * @ret True				Error packet was sent
505
 	strncpy ( error.errmsg, errmsg ? errmsg : strerror ( errno ),
514
 	strncpy ( error.errmsg, errmsg ? errmsg : strerror ( errno ),
506
 		  sizeof ( error.errmsg ) );
515
 		  sizeof ( error.errmsg ) );
507
 	return udp_transmit ( state->server.sin_addr.s_addr,
516
 	return udp_transmit ( state->server.sin_addr.s_addr,
508
-			      state->client.sin_port, state->server.sin_port,
517
+			      state->lport, state->server.sin_port,
509
 			      sizeof ( error ), &error );
518
 			      sizeof ( error ), &error );
510
 }
519
 }
511
 
520
 

Loading…
Cancel
Save