Rizin
unix-like reverse engineering framework and cli tools
packet.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2016 defragger
2 // SPDX-FileCopyrightText: 2014-2016 madprogrammer
3 // SPDX-License-Identifier: GPL-2.0-only
4 
5 #include <errno.h>
6 #include "packet.h"
7 #include "utils.h"
8 #include "dsmsgs.h"
9 
10 #define READ_TIMEOUT (300 * 1000 * 1000)
11 #define FRAME_CHAR 0x7e
12 #define ESC_CHAR 0x7d
13 
14 #define SET_CHANNEL_RESET 0
15 #define SET_CHANNEL_DEBUG 1
16 #define SET_CHANNEL_TEXT 2
17 #define SET_CHANNEL_NAK 0xff
18 
23 
24 static int append(libqnxr_t *g, char ch) {
25  if (g->data_len == DS_DATA_MAX_SIZE + 16) {
26  eprintf("%s: data too long\n", __func__);
27  return -1;
28  }
29 
30  g->recv.data[g->data_len++] = ch;
31  return 0;
32 }
33 
34 static int unpack(libqnxr_t *g) {
35  ut8 modifier = 0;
36  ut8 sum = 0xff;
37 
38  for (; g->read_ptr < g->read_len; g->read_ptr++) {
39  char cur = g->read_buff[g->read_ptr];
40  switch (cur) {
41  case ESC_CHAR:
42  modifier = 0x20;
43  continue;
44  case FRAME_CHAR:
45  /* Ignore multiple start frames */
46  if (g->data_len == 0)
47  continue;
48  if (sum != 0x00) {
49  eprintf("%s: Checksum error\n", __func__);
50  return -1;
51  }
52  g->read_ptr++;
53  return 0;
54  default:
55  cur ^= modifier;
56  sum -= cur;
57  append(g, cur);
58  }
59  modifier = 0;
60  }
61 
62  return 1;
63 }
64 
66  int ret;
67 
68  if (!g) {
69  eprintf("Initialize libqnxr_t first\n");
70  return -1;
71  }
72  g->data_len = 0;
73 
74  // read from network if we've exhausted our buffer
75  // or the buffer is empty
76  if (g->read_len == 0 || g->read_ptr == g->read_len) {
77  while (true) {
78  int ret = rz_socket_ready(g->sock, 0, READ_TIMEOUT);
79  if (ret < 0) {
80  if (errno == EINTR)
81  continue;
82  else
83  return -1;
84  }
85 
86  g->read_ptr = 0;
87  g->read_len = rz_socket_read(g->sock, (void *)g->read_buff,
88 
89  DS_DATA_MAX_SIZE * 2);
90  if (g->read_len <= 0) {
91  g->read_len = 0;
92  eprintf("%s: read failed\n", __func__);
93  return -1;
94  }
95 
96  break;
97  }
98  }
99 
100  ret = unpack(g);
101  if (ret < 0) {
102  eprintf("%s: unpack failed\n", __func__);
103  return -1;
104  }
105 
106  if (g->data_len >= sizeof(struct DShdr)) {
107  if (g->recv.pkt.hdr.channel)
108  g->channelrd = g->recv.pkt.hdr.channel;
109  } else if (g->data_len >= 1) {
110  if (g->recv.data[0] == SET_CHANNEL_NAK) {
111  eprintf("%s: NAK received\n", __func__);
112  g->channelrd = SET_CHANNEL_NAK;
113  return -1;
114  }
115  if (g->recv.data[0] <= SET_CHANNEL_TEXT)
116  g->channelrd = g->recv.data[0];
117  }
118 
119  if (!ret) {
120  // Skip the checksum
121  return g->data_len - 1;
122  }
123 
124  return -1;
125 }
126 
128  return rz_socket_write(g->sock, nak_packet, sizeof(nak_packet));
129 }
130 
132  return rz_socket_write(g->sock, ch_reset_packet, sizeof(ch_reset_packet));
133 }
134 
136  return rz_socket_write(g->sock, ch_debug_packet, sizeof(ch_debug_packet));
137 }
138 
140  return rz_socket_write(g->sock, ch_text_packet, sizeof(ch_text_packet));
141 }
142 
144  if (!g) {
145  eprintf("Initialize libqnxr_t first\n");
146  return -1;
147  }
148 
149  int i;
150  ut8 csum = 0;
151  char *p;
152 
153  p = g->send_buff;
154  *p++ = FRAME_CHAR;
155 
156  for (i = 0; i < g->send_len; i++) {
157  ut8 c = g->tran.data[i];
158  csum += c;
159 
160  switch (c) {
161  case FRAME_CHAR:
162  case ESC_CHAR:
163  *p++ = ESC_CHAR;
164  c ^= 0x20;
165  break;
166  }
167  *p++ = c;
168  }
169 
170  csum ^= 0xff;
171  switch (csum) {
172  case FRAME_CHAR:
173  case ESC_CHAR:
174  *p++ = ESC_CHAR;
175  csum ^= 0x20;
176  break;
177  }
178  *p++ = csum;
179  *p++ = FRAME_CHAR;
180 
181  if (g->channelwr != g->tran.pkt.hdr.channel) {
182  switch (g->tran.pkt.hdr.channel) {
183  case SET_CHANNEL_TEXT:
185  break;
186  case SET_CHANNEL_DEBUG:
188  break;
189  }
190  g->channelwr = g->tran.pkt.hdr.channel;
191  }
192 
193  return rz_socket_write(g->sock, g->send_buff, p - g->send_buff);
194 }
lzma_index ** i
Definition: index.h:629
#define DS_DATA_MAX_SIZE
Definition: dsmsgs.h:102
struct @667 g
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
#define eprintf(x, y...)
Definition: rlcc.c:7
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
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724
#define SET_CHANNEL_NAK
Definition: packet.c:17
static ut8 ch_debug_packet[]
Definition: packet.c:21
#define READ_TIMEOUT
Definition: packet.c:10
static ut8 nak_packet[]
Definition: packet.c:19
#define SET_CHANNEL_DEBUG
Definition: packet.c:15
static ut8 ch_reset_packet[]
Definition: packet.c:20
int qnxr_read_packet(libqnxr_t *g)
Function reads data from the established connection.
Definition: packet.c:65
#define FRAME_CHAR
Definition: packet.c:11
static ut8 ch_text_packet[]
Definition: packet.c:22
int qnxr_send_ch_reset(libqnxr_t *g)
Definition: packet.c:131
int qnxr_send_ch_text(libqnxr_t *g)
Definition: packet.c:139
static int unpack(libqnxr_t *g)
Definition: packet.c:34
static int append(libqnxr_t *g, char ch)
Definition: packet.c:24
#define ESC_CHAR
Definition: packet.c:12
#define SET_CHANNEL_RESET
Definition: packet.c:14
int qnxr_send_nak(libqnxr_t *g)
Definition: packet.c:127
#define SET_CHANNEL_TEXT
Definition: packet.c:16
int qnxr_send_packet(libqnxr_t *g)
sends a packet sends a packet to the established connection
Definition: packet.c:143
int qnxr_send_ch_debug(libqnxr_t *g)
Definition: packet.c:135
#define EINTR
Definition: sftypes.h:114
#define c(i)
Definition: sha256.c:43
Definition: dsmsgs.h:114