|
@@ -19,6 +19,7 @@
|
19
|
19
|
#include <stdio.h>
|
20
|
20
|
#include <string.h>
|
21
|
21
|
#include <byteswap.h>
|
|
22
|
+#include <bios.h>
|
22
|
23
|
#include <gpxe/iobuf.h>
|
23
|
24
|
#include <gpxe/in.h>
|
24
|
25
|
#include <gpxe/if_arp.h>
|
|
@@ -27,7 +28,7 @@
|
27
|
28
|
#include <gpxe/udp.h>
|
28
|
29
|
#include <gpxe/netdevice.h>
|
29
|
30
|
#include <gpxe/gdbstub.h>
|
30
|
|
-#include <bios.h>
|
|
31
|
+#include <gpxe/gdbudp.h>
|
31
|
32
|
|
32
|
33
|
/** @file
|
33
|
34
|
*
|
|
@@ -43,7 +44,6 @@ struct gdb_transport udp_gdb_transport __gdb_transport;
|
43
|
44
|
|
44
|
45
|
static struct net_device *netdev;
|
45
|
46
|
static uint8_t dest_eth[ETH_ALEN];
|
46
|
|
-static uint8_t source_eth[ETH_ALEN];
|
47
|
47
|
static struct sockaddr_in dest_addr;
|
48
|
48
|
static struct sockaddr_in source_addr;
|
49
|
49
|
|
|
@@ -92,11 +92,12 @@ static size_t gdbudp_recv ( char *buf, size_t len ) {
|
92
|
92
|
arphdr->ar_op = htons ( ARPOP_REPLY );
|
93
|
93
|
memswap ( arp_sender_pa ( arphdr ), arp_target_pa ( arphdr ), sizeof ( struct in_addr ) );
|
94
|
94
|
memcpy ( arp_target_ha ( arphdr ), arp_sender_ha ( arphdr ), ETH_ALEN );
|
95
|
|
- memcpy ( arp_sender_ha ( arphdr ), source_eth, ETH_ALEN );
|
|
95
|
+ memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, ETH_ALEN );
|
96
|
96
|
|
97
|
97
|
/* Fix up ethernet header */
|
98
|
98
|
ethhdr = iob_push ( iob, sizeof ( *ethhdr ) );
|
99
|
|
- memswap ( ethhdr->h_source, ethhdr->h_dest, ETH_ALEN );
|
|
99
|
+ memcpy ( ethhdr->h_dest, ethhdr->h_source, ETH_ALEN );
|
|
100
|
+ memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
|
100
|
101
|
|
101
|
102
|
netdev_tx ( netdev, iob );
|
102
|
103
|
continue; /* no need to free iob */
|
|
@@ -196,55 +197,55 @@ static void gdbudp_send ( const char *buf, size_t len ) {
|
196
|
197
|
/* Ethernet header */
|
197
|
198
|
ethhdr = iob_push ( iob, sizeof ( *ethhdr ) );
|
198
|
199
|
memcpy ( ethhdr->h_dest, dest_eth, ETH_ALEN );
|
199
|
|
- memcpy ( ethhdr->h_source, source_eth, ETH_ALEN );
|
|
200
|
+ memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
|
200
|
201
|
ethhdr->h_protocol = htons ( ETH_P_IP );
|
201
|
202
|
|
202
|
203
|
netdev_tx ( netdev, iob );
|
203
|
204
|
}
|
204
|
205
|
|
205
|
|
-static int gdbudp_init ( int argc, char **argv ) {
|
|
206
|
+struct gdb_transport *gdbudp_configure ( const char *name, struct sockaddr_in *addr ) {
|
206
|
207
|
struct settings *settings;
|
207
|
208
|
|
208
|
|
- if ( argc != 1 ) {
|
209
|
|
- printf ( "udp: missing <interface> argument\n" );
|
210
|
|
- return 1;
|
211
|
|
- }
|
212
|
|
-
|
213
|
209
|
/* Release old network device */
|
214
|
210
|
netdev_put ( netdev );
|
215
|
211
|
|
216
|
|
- netdev = find_netdev ( argv[0] );
|
|
212
|
+ netdev = find_netdev ( name );
|
217
|
213
|
if ( !netdev ) {
|
218
|
|
- printf ( "%s: no such interface\n", argv[0] );
|
219
|
|
- return 1;
|
|
214
|
+ return NULL;
|
220
|
215
|
}
|
221
|
216
|
|
222
|
217
|
/* Hold network device */
|
223
|
218
|
netdev_get ( netdev );
|
224
|
219
|
|
225
|
|
- if ( !netdev_link_ok ( netdev ) ) {
|
226
|
|
- printf ( "%s: link not up\n", argv[0] );
|
227
|
|
- netdev_put ( netdev );
|
228
|
|
- netdev = NULL;
|
229
|
|
- return 1;
|
|
220
|
+ /* Source UDP port */
|
|
221
|
+ source_addr.sin_port = ( addr && addr->sin_port ) ? addr->sin_port : htons ( DEFAULT_PORT );
|
|
222
|
+
|
|
223
|
+ /* Source IP address */
|
|
224
|
+ if ( addr && addr->sin_addr.s_addr ) {
|
|
225
|
+ source_addr.sin_addr.s_addr = addr->sin_addr.s_addr;
|
|
226
|
+ } else {
|
|
227
|
+ settings = netdev_settings ( netdev );
|
|
228
|
+ fetch_ipv4_setting ( settings, &ip_setting, &source_addr.sin_addr );
|
|
229
|
+ if ( source_addr.sin_addr.s_addr == 0 ) {
|
|
230
|
+ netdev_put ( netdev );
|
|
231
|
+ netdev = NULL;
|
|
232
|
+ return NULL;
|
|
233
|
+ }
|
230
|
234
|
}
|
231
|
235
|
|
232
|
|
- /* Load network settings from device. We keep the MAC address,
|
233
|
|
- * IP address, and UDP port. The MAC and IP could be fetched
|
234
|
|
- * from the network device each time they are used in rx/tx.
|
235
|
|
- * Storing a separate copy makes it possible to use different
|
236
|
|
- * MAC/IP settings than the network stack. */
|
237
|
|
- memcpy ( source_eth, netdev->ll_addr, ETH_ALEN );
|
238
|
|
- source_addr.sin_port = htons ( DEFAULT_PORT );
|
239
|
|
- settings = netdev_settings ( netdev );
|
240
|
|
- fetch_ipv4_setting ( settings, &ip_setting, &source_addr.sin_addr );
|
241
|
|
- if ( source_addr.sin_addr.s_addr == 0 ) {
|
242
|
|
- printf ( "%s: no IP address configured\n", argv[0] );
|
243
|
|
- netdev_put ( netdev );
|
244
|
|
- netdev = NULL;
|
|
236
|
+ return &udp_gdb_transport;
|
|
237
|
+}
|
|
238
|
+
|
|
239
|
+static int gdbudp_init ( int argc, char **argv ) {
|
|
240
|
+ if ( argc != 1 ) {
|
|
241
|
+ printf ( "udp: missing <interface> argument\n" );
|
245
|
242
|
return 1;
|
246
|
243
|
}
|
247
|
244
|
|
|
245
|
+ if ( !gdbudp_configure ( argv[0], NULL ) ) {
|
|
246
|
+ printf ( "%s: device does not exist or has no IP address\n", argv[0] );
|
|
247
|
+ return 1;
|
|
248
|
+ }
|
248
|
249
|
return 0;
|
249
|
250
|
}
|
250
|
251
|
|