1 #include <syslinux/pxe_api.h> 2 #include <com32.h> 3 #include <core.h> 4 #include <net.h> 5 #include <pxe.h> 6 #include <minmax.h> 7 8 /* Common receive buffer */ 9 static __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16); 10 11 extern uint16_t get_port(void); 12 extern void free_port(uint16_t); 13 14 const struct url_scheme url_schemes[] = { 15 { "tftp", tftp_open, 0 }, 16 { NULL, NULL, 0 } 17 }; 18 19 /** 20 * Open a socket 21 * 22 * @param:socket, the socket to open 23 * 24 * @out: error code, 0 on success, -1 on failure 25 */ 26 int core_udp_open(struct pxe_pvt_inode *socket __unused) 27 { 28 struct net_private_tftp *priv = &socket->net.tftp; 29 30 /* Allocate local UDP port number */ 31 priv->localport = get_port(); 32 33 return 0; 34 } 35 36 /** 37 * Close a socket 38 * 39 * @param:socket, the socket to open 40 */ 41 void core_udp_close(struct pxe_pvt_inode *socket) 42 { 43 struct net_private_tftp *priv = &socket->net.tftp; 44 45 if (priv->localport) 46 free_port(priv->localport); 47 } 48 49 /** 50 * Establish a connection on an open socket 51 * 52 * @param:socket, the open socket 53 * @param:ip, the ip address 54 * @param:port, the port number, host-byte order 55 */ 56 void core_udp_connect(struct pxe_pvt_inode *socket, uint32_t ip, 57 uint16_t port) 58 { 59 struct net_private_tftp *priv = &socket->net.tftp; 60 61 socket->tftp_remoteport = htons(port); 62 priv->remoteip = ip; 63 64 } 65 66 /** 67 * Tear down a connection on an open socket 68 * 69 * @param:socket, the open socket 70 */ 71 void core_udp_disconnect(struct pxe_pvt_inode *socket __unused) 72 { 73 } 74 75 /** 76 * Read data from the network stack 77 * 78 * @param:socket, the open socket 79 * @param:buf, location of buffer to store data 80 * @param:buf_len, size of buffer 81 82 * @out: src_ip, ip address of the data source 83 * @out: src_port, port number of the data source, host-byte order 84 */ 85 int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len, 86 uint32_t *src_ip, uint16_t *src_port) 87 { 88 static __lowmem struct s_PXENV_UDP_READ udp_read; 89 struct net_private_tftp *priv = &socket->net.tftp; 90 uint16_t bytes; 91 int err; 92 93 udp_read.status = 0; 94 udp_read.buffer = FAR_PTR(packet_buf); 95 udp_read.buffer_size = PKTBUF_SIZE; 96 udp_read.dest_ip = IPInfo.myip; 97 udp_read.d_port = priv->localport; 98 99 err = pxe_call(PXENV_UDP_READ, &udp_read); 100 if (err) 101 return err; 102 103 if (udp_read.status) 104 return udp_read.status; 105 106 bytes = min(udp_read.buffer_size, *buf_len); 107 memcpy(buf, packet_buf, bytes); 108 109 *src_ip = udp_read.src_ip; 110 *src_port = ntohs(udp_read.s_port); 111 *buf_len = bytes; 112 113 return 0; 114 } 115 116 /** 117 * Send a UDP packet. 118 * 119 * @param:socket, the open socket 120 * @param:data, data buffer to send 121 * @param:len, size of data bufer 122 */ 123 void core_udp_send(struct pxe_pvt_inode *socket, const void *data, size_t len) 124 { 125 static __lowmem struct s_PXENV_UDP_WRITE udp_write; 126 struct net_private_tftp *priv = &socket->net.tftp; 127 void *lbuf; 128 uint16_t tid; 129 130 lbuf = lmalloc(len); 131 if (!lbuf) 132 return; 133 134 memcpy(lbuf, data, len); 135 136 tid = priv->localport; /* TID(local port No) */ 137 udp_write.buffer = FAR_PTR(lbuf); 138 udp_write.ip = priv->remoteip; 139 udp_write.gw = gateway(udp_write.ip); 140 udp_write.src_port = tid; 141 udp_write.dst_port = socket->tftp_remoteport; 142 udp_write.buffer_size = len; 143 144 pxe_call(PXENV_UDP_WRITE, &udp_write); 145 146 lfree(lbuf); 147 } 148 149 /** 150 * Send a UDP packet to a destination 151 * 152 * @param:socket, the open socket 153 * @param:data, data buffer to send 154 * @param:len, size of data bufer 155 * @param:ip, the ip address 156 * @param:port, the port number, host-byte order 157 */ 158 void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data, size_t len, 159 uint32_t ip, uint16_t port) 160 { 161 static __lowmem struct s_PXENV_UDP_WRITE udp_write; 162 struct net_private_tftp *priv = &socket->net.tftp; 163 void *lbuf; 164 uint16_t tid; 165 166 lbuf = lmalloc(len); 167 if (!lbuf) 168 return; 169 170 memcpy(lbuf, data, len); 171 172 tid = priv->localport; /* TID(local port No) */ 173 udp_write.buffer = FAR_PTR(lbuf); 174 udp_write.ip = ip; 175 udp_write.gw = gateway(udp_write.ip); 176 udp_write.src_port = tid; 177 udp_write.dst_port = htons(port); 178 udp_write.buffer_size = len; 179 180 pxe_call(PXENV_UDP_WRITE, &udp_write); 181 182 lfree(lbuf); 183 } 184 185 186 /** 187 * Network stack-specific initialization 188 * 189 * Initialize UDP stack 190 */ 191 void net_core_init(void) 192 { 193 int err; 194 static __lowmem struct s_PXENV_UDP_OPEN udp_open; 195 udp_open.src_ip = IPInfo.myip; 196 err = pxe_call(PXENV_UDP_OPEN, &udp_open); 197 if (err || udp_open.status) { 198 printf("Failed to initialize UDP stack "); 199 printf("%d\n", udp_open.status); 200 kaboom(); 201 } 202 } 203 204 void probe_undi(void) 205 { 206 } 207 208 void pxe_init_isr(void) 209 { 210 } 211 212 int reset_pxe(void) 213 { 214 static __lowmem struct s_PXENV_UDP_CLOSE udp_close; 215 int err = 0; 216 217 pxe_idle_cleanup(); 218 219 pxe_call(PXENV_UDP_CLOSE, &udp_close); 220 221 return err; 222 } 223