#include <stdio.h>
#include <string.h>
#include <byteswap.h>
#include <gpxe/iobuf.h>
#include <gpxe/in.h>
#include <gpxe/if_arp.h>
#include <gpxe/if_ether.h>
#include <gpxe/ip.h>
#include <gpxe/udp.h>
#include <gpxe/netdevice.h>
#include <gpxe/nap.h>
#include <gpxe/gdbstub.h>
#include <gpxe/gdbudp.h>
Go to the source code of this file.
Enumerations | |
| enum | { DEFAULT_PORT = 43770 } |
Functions | |
| static void | gdbudp_ensure_netdev_open (struct net_device *netdev) |
| static size_t | gdbudp_recv (char *buf, size_t len) |
| static void | gdbudp_send (const char *buf, size_t len) |
| struct gdb_transport * | gdbudp_configure (const char *name, struct sockaddr_in *addr) |
| static int | gdbudp_init (int argc, char **argv) |
Variables | |
| struct gdb_transport udp_gdb_transport | __gdb_transport |
| static struct net_device * | netdev |
| static uint8_t | dest_eth [ETH_ALEN] |
| static struct sockaddr_in | dest_addr |
| static struct sockaddr_in | source_addr |
Definition in file gdbudp.c.
| anonymous enum |
Definition at line 39 of file gdbudp.c.
00039 { 00040 DEFAULT_PORT = 43770, /* UDP listen port */ 00041 };
| static void gdbudp_ensure_netdev_open | ( | struct net_device * | netdev | ) | [static] |
Definition at line 50 of file gdbudp.c.
References assert, and netdev_open().
Referenced by gdbudp_recv(), and gdbudp_send().
00050 { 00051 /* The device may have been closed between breakpoints */ 00052 assert ( netdev ); 00053 netdev_open ( netdev ); 00054 00055 /* Strictly speaking, we may need to close the device when leaving the interrupt handler */ 00056 }
Definition at line 58 of file gdbudp.c.
References arphdr::ar_hln, arphdr::ar_hrd, arphdr::ar_op, arphdr::ar_pln, arphdr::ar_pro, arp_sender_ha(), arp_sender_pa(), arp_target_ha(), arp_target_pa(), ARPHRD_ETHER, ARPOP_REPLY, ARPOP_REQUEST, cpu_nap(), io_buffer::data, udp_header::dest, iphdr::dest, dest_addr, dest_eth, ETH_ALEN, ETH_P_ARP, ETH_P_IP, free_iob(), gdbudp_ensure_netdev_open(), ethhdr::h_dest, ethhdr::h_protocol, ethhdr::h_source, htons, iob_len(), iob_pull, iob_push, IP_UDP, udp_header::len, net_device::ll_addr, memcpy, netdev_poll(), netdev_rx_dequeue(), netdev_tx(), ntohs, NULL, iphdr::protocol, in_addr::s_addr, sockaddr_in::sin_addr, sockaddr_in::sin_port, source_addr, udp_header::src, and iphdr::src.
00058 { 00059 struct io_buffer *iob; 00060 struct ethhdr *ethhdr; 00061 struct arphdr *arphdr; 00062 struct iphdr *iphdr; 00063 struct udp_header *udphdr; 00064 size_t payload_len; 00065 00066 gdbudp_ensure_netdev_open ( netdev ); 00067 00068 for ( ; ; ) { 00069 netdev_poll ( netdev ); 00070 while ( ( iob = netdev_rx_dequeue ( netdev ) ) != NULL ) { 00071 /* Ethernet header */ 00072 if ( iob_len ( iob ) < sizeof ( *ethhdr ) ) { 00073 goto bad_packet; 00074 } 00075 ethhdr = iob->data; 00076 iob_pull ( iob, sizeof ( *ethhdr ) ); 00077 00078 /* Handle ARP requests so the client can find our MAC */ 00079 if ( ethhdr->h_protocol == htons ( ETH_P_ARP ) ) { 00080 arphdr = iob->data; 00081 if ( iob_len ( iob ) < sizeof ( *arphdr ) + 2 * ( ETH_ALEN + sizeof ( struct in_addr ) ) || 00082 arphdr->ar_hrd != htons ( ARPHRD_ETHER ) || 00083 arphdr->ar_pro != htons ( ETH_P_IP ) || 00084 arphdr->ar_hln != ETH_ALEN || 00085 arphdr->ar_pln != sizeof ( struct in_addr ) || 00086 arphdr->ar_op != htons ( ARPOP_REQUEST ) || 00087 * ( uint32_t * ) arp_target_pa ( arphdr ) != source_addr.sin_addr.s_addr ) { 00088 goto bad_packet; 00089 } 00090 00091 /* Generate an ARP reply */ 00092 arphdr->ar_op = htons ( ARPOP_REPLY ); 00093 memswap ( arp_sender_pa ( arphdr ), arp_target_pa ( arphdr ), sizeof ( struct in_addr ) ); 00094 memcpy ( arp_target_ha ( arphdr ), arp_sender_ha ( arphdr ), ETH_ALEN ); 00095 memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, ETH_ALEN ); 00096 00097 /* Fix up ethernet header */ 00098 ethhdr = iob_push ( iob, sizeof ( *ethhdr ) ); 00099 memcpy ( ethhdr->h_dest, ethhdr->h_source, ETH_ALEN ); 00100 memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN ); 00101 00102 netdev_tx ( netdev, iob ); 00103 continue; /* no need to free iob */ 00104 } 00105 00106 if ( ethhdr->h_protocol != htons ( ETH_P_IP ) ) { 00107 goto bad_packet; 00108 } 00109 00110 /* IP header */ 00111 if ( iob_len ( iob ) < sizeof ( *iphdr ) ) { 00112 goto bad_packet; 00113 } 00114 iphdr = iob->data; 00115 iob_pull ( iob, sizeof ( *iphdr ) ); 00116 if ( iphdr->protocol != IP_UDP || iphdr->dest.s_addr != source_addr.sin_addr.s_addr ) { 00117 goto bad_packet; 00118 } 00119 00120 /* UDP header */ 00121 if ( iob_len ( iob ) < sizeof ( *udphdr ) ) { 00122 goto bad_packet; 00123 } 00124 udphdr = iob->data; 00125 if ( udphdr->dest != source_addr.sin_port ) { 00126 goto bad_packet; 00127 } 00128 00129 /* Learn the remote connection details */ 00130 memcpy ( dest_eth, ethhdr->h_source, ETH_ALEN ); 00131 dest_addr.sin_addr.s_addr = iphdr->src.s_addr; 00132 dest_addr.sin_port = udphdr->src; 00133 00134 /* Payload */ 00135 payload_len = ntohs ( udphdr->len ); 00136 if ( payload_len < sizeof ( *udphdr ) || payload_len > iob_len ( iob ) ) { 00137 goto bad_packet; 00138 } 00139 payload_len -= sizeof ( *udphdr ); 00140 iob_pull ( iob, sizeof ( *udphdr ) ); 00141 if ( payload_len > len ) { 00142 goto bad_packet; 00143 } 00144 memcpy ( buf, iob->data, payload_len ); 00145 00146 free_iob ( iob ); 00147 return payload_len; 00148 00149 bad_packet: 00150 free_iob ( iob ); 00151 } 00152 cpu_nap(); 00153 } 00154 }
| static void gdbudp_send | ( | const char * | buf, | |
| size_t | len | |||
| ) | [static] |
Definition at line 156 of file gdbudp.c.
References alloc_iob(), iphdr::chksum, udp_header::chksum, iphdr::dest, udp_header::dest, dest_addr, dest_eth, ETH_ALEN, ETH_P_IP, gdbudp_ensure_netdev_open(), ethhdr::h_dest, ethhdr::h_protocol, ethhdr::h_source, htons, iob_len(), iob_push, iob_put, iob_reserve, IP_TOS, IP_TTL, IP_UDP, IP_VER, iphdr::len, udp_header::len, net_device::ll_addr, memcpy, memset(), netdev_tx(), iphdr::protocol, in_addr::s_addr, iphdr::service, sockaddr_in::sin_addr, sockaddr_in::sin_port, source_addr, iphdr::src, udp_header::src, tcpip_chksum(), iphdr::ttl, and iphdr::verhdrlen.
00156 { 00157 struct io_buffer *iob; 00158 struct ethhdr *ethhdr; 00159 struct iphdr *iphdr; 00160 struct udp_header *udphdr; 00161 00162 /* Check that we are connected */ 00163 if ( dest_addr.sin_port == 0 ) { 00164 return; 00165 } 00166 00167 gdbudp_ensure_netdev_open ( netdev ); 00168 00169 iob = alloc_iob ( sizeof ( *ethhdr ) + sizeof ( *iphdr ) + sizeof ( *udphdr ) + len ); 00170 if ( !iob ) { 00171 return; 00172 } 00173 00174 /* Payload */ 00175 iob_reserve ( iob, sizeof ( *ethhdr ) + sizeof ( *iphdr ) + sizeof ( *udphdr ) ); 00176 memcpy ( iob_put ( iob, len ), buf, len ); 00177 00178 /* UDP header */ 00179 udphdr = iob_push ( iob, sizeof ( *udphdr ) ); 00180 udphdr->src = source_addr.sin_port; 00181 udphdr->dest = dest_addr.sin_port; 00182 udphdr->len = htons ( iob_len ( iob ) ); 00183 udphdr->chksum = 0; /* optional and we are not using it */ 00184 00185 /* IP header */ 00186 iphdr = iob_push ( iob, sizeof ( *iphdr ) ); 00187 memset ( iphdr, 0, sizeof ( *iphdr ) ); 00188 iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) ); 00189 iphdr->service = IP_TOS; 00190 iphdr->len = htons ( iob_len ( iob ) ); 00191 iphdr->ttl = IP_TTL; 00192 iphdr->protocol = IP_UDP; 00193 iphdr->dest.s_addr = dest_addr.sin_addr.s_addr; 00194 iphdr->src.s_addr = source_addr.sin_addr.s_addr; 00195 iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) ); 00196 00197 /* Ethernet header */ 00198 ethhdr = iob_push ( iob, sizeof ( *ethhdr ) ); 00199 memcpy ( ethhdr->h_dest, dest_eth, ETH_ALEN ); 00200 memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN ); 00201 ethhdr->h_protocol = htons ( ETH_P_IP ); 00202 00203 netdev_tx ( netdev, iob ); 00204 }
| struct gdb_transport* gdbudp_configure | ( | const char * | name, | |
| struct sockaddr_in * | addr | |||
| ) | [read] |
Definition at line 206 of file gdbudp.c.
References DEFAULT_PORT, fetch_ipv4_setting(), find_netdev(), htons, netdev_get(), netdev_put(), netdev_settings(), NULL, in_addr::s_addr, sockaddr_in::sin_addr, sockaddr_in::sin_port, and source_addr.
Referenced by gdbudp_init().
00206 { 00207 struct settings *settings; 00208 00209 /* Release old network device */ 00210 netdev_put ( netdev ); 00211 00212 netdev = find_netdev ( name ); 00213 if ( !netdev ) { 00214 return NULL; 00215 } 00216 00217 /* Hold network device */ 00218 netdev_get ( netdev ); 00219 00220 /* Source UDP port */ 00221 source_addr.sin_port = ( addr && addr->sin_port ) ? addr->sin_port : htons ( DEFAULT_PORT ); 00222 00223 /* Source IP address */ 00224 if ( addr && addr->sin_addr.s_addr ) { 00225 source_addr.sin_addr.s_addr = addr->sin_addr.s_addr; 00226 } else { 00227 settings = netdev_settings ( netdev ); 00228 fetch_ipv4_setting ( settings, &ip_setting, &source_addr.sin_addr ); 00229 if ( source_addr.sin_addr.s_addr == 0 ) { 00230 netdev_put ( netdev ); 00231 netdev = NULL; 00232 return NULL; 00233 } 00234 } 00235 00236 return &udp_gdb_transport; 00237 }
| static int gdbudp_init | ( | int | argc, | |
| char ** | argv | |||
| ) | [static] |
Definition at line 239 of file gdbudp.c.
References gdbudp_configure(), NULL, and printf().
00239 { 00240 if ( argc != 1 ) { 00241 printf ( "udp: missing <interface> argument\n" ); 00242 return 1; 00243 } 00244 00245 if ( !gdbudp_configure ( argv[0], NULL ) ) { 00246 printf ( "%s: device does not exist or has no IP address\n", argv[0] ); 00247 return 1; 00248 } 00249 return 0; 00250 }
struct gdb_transport udp_gdb_transport __gdb_transport [read] |
Initial value:
{
.name = "udp",
.init = gdbudp_init,
.send = gdbudp_send,
.recv = gdbudp_recv,
}
struct net_device* netdev [static] |
Definition at line 45 of file gdbudp.c.
Referenced by a3c90x_probe(), a3c90x_remove(), alloc_etherdev(), alloc_ipoibdev(), alloc_netdev(), aoeboot(), atl1e_check_link(), atl1e_clean_rx_irq(), atl1e_down(), atl1e_probe(), atl1e_remove(), atl1e_up(), autoboot(), b44_probe(), b44_remove(), close_all_netdevs(), dhcp_exec(), e1000_probe(), e1000_remove(), e1000e_probe(), e1000e_remove(), efab_probe(), efab_remove(), efi_snp_driver_start(), efi_snp_driver_supported(), efi_snp_netdev(), efi_snp_set_mode(), find_netdev(), find_netdev_by_location(), free_netdev(), ifcommon_do_all(), ifcommon_do_list(), ifec_pci_probe(), ifec_pci_remove(), igb_probe(), igb_remove(), ipoib_complete_recv(), ipoib_link_state_changed(), ipoib_probe(), ipoib_remove(), ipv4_create_routes(), iscsiboot(), last_opened_netdev(), legacy_irq(), legacy_probe(), legacy_remove(), myri10ge_pci_probe(), myri10ge_pci_remove(), natsemi_probe(), natsemi_remove(), net80211_alloc(), net80211_ll_pull(), net_step(), netdev_fetch(), netdev_store(), parse_settings_name(), phantom_probe(), phantom_remove(), pnic_probe(), pnic_remove(), pxe_exec(), pxebs_exec(), pxenv_start_undi(), rtl8169_probe(), rtl8169_remove(), rtl_probe(), rtl_remove(), undinet_probe(), undinet_remove(), vxge_irq(), and vxge_xmit_compl().
struct sockaddr_in dest_addr [static] |
struct sockaddr_in source_addr [static] |
Definition at line 48 of file gdbudp.c.
Referenced by gdbudp_configure(), gdbudp_recv(), and gdbudp_send().
1.5.7.1