Rizin
unix-like reverse engineering framework and cli tools
packet.h File Reference
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "libgdbr.h"
#include <stdio.h>

Go to the source code of this file.

Functions

int send_packet (libgdbr_t *g)
 sends a packet sends a packet to the established connection More...
 
int read_packet (libgdbr_t *g, bool vcont)
 Function reads data from the established connection. More...
 
int pack (libgdbr_t *g, const char *msg)
 

Function Documentation

◆ pack()

int pack ( libgdbr_t g,
const char *  msg 
)

Definition at line 206 of file packet.c.

206  {
207  int run_len;
208  size_t msg_len;
209  const char *src;
210  char prev;
211  if (!g || !msg) {
212  return -1;
213  }
214  msg_len = strlen(msg);
215  if (msg_len > g->send_max + 5) {
216  eprintf("%s: message too long: %s", __func__, msg);
217  return -1;
218  }
219  if (!g->send_buff) {
220  return -1;
221  }
222  g->send_buff[0] = '$';
223  g->send_len = 1;
224  src = msg;
225  while (*src) {
226  if (*src == '#' || *src == '$' || *src == '}') {
227  msg_len += 1;
228  if (msg_len > g->send_max + 5) {
229  eprintf("%s: message too long: %s", __func__, msg);
230  return -1;
231  }
232  g->send_buff[g->send_len++] = '}';
233  g->send_buff[g->send_len++] = *src++ ^ 0x20;
234  continue;
235  }
236  g->send_buff[g->send_len++] = *src++;
237  if (!g->is_server) {
238  continue;
239  }
240  prev = *(src - 1);
241  run_len = 0;
242  while (src[run_len] == prev) {
243  run_len++;
244  }
245  if (run_len < 3) { // 3 specified in RSP documentation
246  while (run_len--) {
247  g->send_buff[g->send_len++] = *src++;
248  }
249  continue;
250  }
251  run_len += 29; // Encode as printable character
252  if (run_len == 35 || run_len == 36) { // Cannot use '$' or '#'
253  run_len = 34;
254  } else if (run_len > 126) { // Max printable ascii value
255  run_len = 126;
256  }
257  g->send_buff[g->send_len++] = '*';
258  g->send_buff[g->send_len++] = run_len;
259  msg_len -= run_len - 27; // 2 chars to encode run length
260  src += run_len - 29;
261  }
262  g->send_buff[g->send_len] = '\0';
263  snprintf(g->send_buff + g->send_len, 4, "#%.2x", cmd_checksum(g->send_buff + 1));
264  g->send_len += 3;
265  return g->send_len;
266 }
lzma_index * src
Definition: index.h:567
struct @667 g
snprintf
Definition: kernel.h:364
#define eprintf(x, y...)
Definition: rlcc.c:7
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
uint8_t cmd_checksum(const char *command)
Definition: utils.c:16

References cmd_checksum(), eprintf, g, msg, snprintf, and src.

Referenced by send_msg(), xprint::to_x(), and xprint::to_x_32().

◆ read_packet()

int read_packet ( libgdbr_t g,
bool  vcont 
)

Function reads data from the established connection.

Parameters
gthe "instance" of the current libgdbr session
vcontwhether it's called to receive reply to a vcont packet
Returns
a failure code (currently -1) or 0 if call successfully

Definition at line 143 of file packet.c.

143  {
144  struct parse_ctx ctx = { 0 };
145  int ret, i;
146  if (!g) {
147  eprintf("Initialize libgdbr_t first\n");
148  return -1;
149  }
150  g->data_len = 0;
151  if (g->read_len > 0) {
152  if (unpack(g, &ctx, g->read_len) == 0) {
153  // TODO: Evaluate if partial packets are clubbed
154  g->data[g->data_len] = '\0';
155  if (g->server_debug) {
156  eprintf("getpkt (\"%s\"); %s\n", g->data,
157  g->no_ack ? "[no ack sent]" : "[sending ack]");
158  }
159  return 0;
160  }
161  }
162  g->data_len = 0;
163  for (i = 0; i < g->num_retries && !g->isbreaked; vcont ? 0 : i++) {
164  ret = rz_socket_ready(g->sock, 0, READ_TIMEOUT);
165  if (ret == 0 && !vcont) {
166  continue;
167  }
168  if (ret <= 0) {
169  return -1;
170  }
171  int sz = rz_socket_read(g->sock, (void *)g->read_buff, g->read_max - 1);
172  if (sz <= 0) {
173  eprintf("%s: read failed\n", __func__);
174  return -1;
175  }
176  ret = unpack(g, &ctx, sz);
177  if (ret < 0) {
178  eprintf("%s: unpack failed\n", __func__);
179  return -1;
180  }
181  if (!ret) {
182  g->data[g->data_len] = '\0';
183  if (g->server_debug) {
184  eprintf("getpkt (\"%s\"); %s\n", g->data,
185  g->no_ack ? "[no ack sent]" : "[sending ack]");
186  }
187  return 0;
188  }
189  }
190  return -1;
191 }
lzma_index ** i
Definition: index.h:629
RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs)
Definition: socket.c:688
RZ_API void RZ_API int rz_socket_read(RzSocket *s, ut8 *read, int len)
Definition: socket.c:783
#define READ_TIMEOUT
Definition: packet.c:7
static int unpack(libgdbr_t *g, struct parse_ctx *ctx, int len)
Definition: packet.c:43

◆ send_packet()

int send_packet ( libgdbr_t g)

sends a packet sends a packet to the established connection

Parameters
gthe "instance" of the current libgdbr session
Returns
a failure code (currently -1) or 0 if call successfully

Definition at line 193 of file packet.c.

193  {
194  if (!g) {
195  eprintf("Initialize libgdbr_t first\n");
196  return -1;
197  }
198  if (g->server_debug) {
199  g->send_buff[g->send_len] = '\0';
200  eprintf("putpkt (\"%s\"); %s\n", g->send_buff,
201  g->no_ack ? "[noack mode]" : "[looking for ack]");
202  }
203  return rz_socket_write(g->sock, g->send_buff, g->send_len);
204 }
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724

References eprintf, g, and rz_socket_write().

Referenced by send_msg().