Перейти к содержанию
    

подскажите код для ответа на PING (то есть генерация ICMP echo response)

то есть имеем строку с ICMP echo request, нужно ответить так, чтобы хост пославший риквест сказал, что ОК

я очень приблизительно представляю как это делать - ну там адреса сорс/дестинэйшин поменять, тип пакета, таймштамп. CRC наверно нужно посчитать и т.д.

уровень пакетов IP4, то есть вот такие

код хотелось бы не выковыривать из lwip или еще откуда-то, а небольшой С файлик без зависимостей...

запрос

17:57:14.906687 IP (tos 0x0, ttl 64, id 27939, offset 0, flags [DF], proto ICMP (1), length 84)
    192.168.0.23 > au0-srv: ICMP echo request, id 26, seq 1, length 64
	0x0000:  50eb f6bc 5508 6cb3 111b ecb6 0800 4500
	0x0010:  0054 6d23 4000 4001 4c03 c0a8 0017 c0a8
	0x0020:  001b 0800 b813 001a 0001 bac5 0c63 0000
	0x0030:  0000 acd5 0d00 0000 0000 1011 1213 1415
	0x0040:  1617 1819 1a1b 1c1d 1e1f 2021 2223 2425
	0x0050:  2627 2829 2a2b 2c2d 2e2f 3031 3233 3435
	0x0060:  3637

ответ

17:57:14.906713 IP (tos 0x0, ttl 64, id 14118, offset 0, flags [none], proto ICMP (1), length 84)
    au0-srv > 192.168.0.23: ICMP echo reply, id 26, seq 1, length 64
	0x0000:  6cb3 111b ecb6 50eb f6bc 5508 0800 4500
	0x0010:  0054 3726 0000 4001 c200 c0a8 001b c0a8
	0x0020:  0017 0000 c013 001a 0001 bac5 0c63 0000
	0x0030:  0000 acd5 0d00 0000 0000 1011 1213 1415
	0x0040:  1617 1819 1a1b 1c1d 1e1f 2021 2223 2425
	0x0050:  2627 2829 2a2b 2c2d 2e2f 3031 3233 3435
	0x0060:  3637

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

IMHO проще "выковырять". Если сделать в урезанном-упрощенном варианте, то есть риск что не все запросы request будут обслужены корректно, соотв-но будут давать ошибку на стороне запросчика.

https://www.rfc-editor.org/rfc/rfc792 из wiki    "echo", "Echo Reply"

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 часов назад, yes сказал:

то есть имеем строку с ICMP echo request, нужно ответить так, чтобы хост пославший риквест сказал, что ОК

http://www.xserver.ru/computer/protokol/tcpip/3/6.shtml

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/29/2022 at 4:10 PM, yes said:

то есть имеем строку с ICMP echo request, нужно ответить так, чтобы хост пославший риквест сказал, что ОК

я очень приблизительно представляю как это делать - ну там адреса сорс/дестинэйшин поменять, тип пакета, таймштамп. CRC наверно нужно посчитать и т.д.

код хотелось бы не выковыривать из lwip или еще откуда-то, а небольшой С файлик без зависимостей...

Насколько я понимаю мне достаточно было поменять местами оба MAC и оба IP:

Spoiler
void gmac_process_ip_packet(uint8_t *p_uc_data, uint32_t ul_size)
{
uint32_t i;
uint32_t ul_icmp_len;
int32_t ul_rc = GMAC_OK;

// avoid Cppcheck Warning 
UNUSED(ul_size);

if ( 1 != MACinFilter(p_uc_data) ) {Print0("not my MAC"); return;}
//------------------------

p_ethernet_header_t p_eth = (p_ethernet_header_t) p_uc_data;
p_ip_header_t p_ip_header = (p_ip_header_t) (p_uc_data + ETH_HEADER_SIZE);

p_icmp_echo_header_t p_icmp_echo = (p_icmp_echo_header_t) ((int8_t *) p_ip_header + ETH_IP_HEADER_SIZE);

// Print0_IP (&(p_ip_header->ip_dst[0]), "IP Dst ");
// Print0_IP (&(p_ip_header->ip_src[0]), "IP Srs ");
// Print0_MAC (&(p_eth->et_dest[0]),     "MAC Dst ");
// Print0_MAC (&(p_eth->et_src[0]),      "MAC Srs ");

HMC=GetHostMAC(p_uc_data);


//Print0V(ul_size,"len ");//106
//for (i=0;i<ul_size;i++) Print0VHM(p_uc_data[i],16); Print0VHM(0,0);

switch (p_ip_header->ip_p) 
	{
	case IP_PROT_ICMP:	if (p_icmp_echo->type == ICMP_ECHO_REQUEST) 
							{
							p_icmp_echo->type = ICMP_ECHO_REPLY;
							p_icmp_echo->code = 0;
							p_icmp_echo->cksum = 0;

							// Checksum of the ICMP message 
							ul_icmp_len = (SWAP16(p_ip_header->ip_len) - ETH_IP_HEADER_SIZE);
							if (ul_icmp_len % 2) 
								{
								*((uint8_t *) p_icmp_echo + ul_icmp_len) = 0;
								ul_icmp_len++;
								}
							ul_icmp_len = ul_icmp_len / sizeof(uint16_t);
							p_icmp_echo->cksum = SWAP16(gmac_icmp_checksum((uint16_t *)p_icmp_echo, ul_icmp_len));
							
							// Swap the IP destination  address and the IP source address 
							for (i = 0; i < 4; i++) 
								{
								p_ip_header->ip_dst[i] = p_ip_header->ip_src[i];
								p_ip_header->ip_src[i] = gs_uc_ip_address[i];
								}
							
							// Swap ethernet destination address and ethernet source address 
							for (i = 0; i < 6; i++) 
								{
								p_eth->et_dest[i] = p_eth->et_src[i];
								p_eth->et_src[i] = gs_uc_mac_address[i];
								}
								
							// Send the echo_reply 
							#if (SAM4E)
										ul_rc = gmac_dev_write(&gs_gmac_dev, p_uc_data, SWAP16(p_ip_header->ip_len) + 14, NULL);
							#else
										ul_rc = gmac_dev_write(&gs_gmac_dev, GMAC_QUE_0, p_uc_data, SWAP16(p_ip_header->ip_len) + 14, NULL);
							#endif
							if (ul_rc != GMAC_OK) { Print0VH(ul_rc,"!!! Error: ICMP Send = ");	}
							}
							break;

	case IP_PROT_TCP:	if  (HMC==1) { /* spoiler */} break;
		
					
	default: 		break;
	}
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

без описания структур и дефайнов

ICMP_ECHO_REPLY, p_ip_header-> и т.п. 

пример мне не поможет :)

---------------

наверно проще будет поднять стек, чем такую заглушку поставить...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, _4afc_ сказал:

Насколько я понимаю мне достаточно было поменять местами оба MAC и оба IP:

http://www.xserver.ru/computer/protokol/tcpip/3/6.shtml  говорит что не достаточно.

хотя... может у вас свой собственный TCP/IP?  :wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/30/2022 at 3:23 PM, jcxz said:

http://www.xserver.ru/computer/protokol/tcpip/3/6.shtml  говорит что не достаточно.

хотя... может у вас свой собственный TCP/IP?  :wink:

 

У меня "Атмеловский". А что в ваших дампах много ещё отличий?

 

ICMP_ECHO_REPLY:

Spoiler
/** Ethernet types */
#define ETH_PROT_IP             0x0800 /**< 2048  (0x0800) IPv4 */
#define ETH_PROT_ARP            0x0806 /**< 2054  (0x0806) ARP */
#define ETH_PROT_APPLETALK      0x8019 /**< 32923 (0x8019) Appletalk */
#define ETH_PROT_IPV6           0x86DD /**< 34525 (0x86DD) IPv6 */

/** ARP OP codes */
#define ARP_REQUEST             0x0001 /**< ARP Request packet */
#define ARP_REPLY               0x0002 /**< ARP Reply packet */

/** IP protocols code */
/* http://www.iana.org/assignments/protocol-numbers */
#define IP_PROT_ICMP            1
#define IP_PROT_IP              4
#define IP_PROT_TCP             6
#define IP_PROT_UDP             17



/** ICMP types */
/* http://www.iana.org/assignments/icmp-parameters */
#define ICMP_ECHO_REPLY         0x00 /**< Echo reply (used to ping) */
/* 1 and 2 Reserved */
#define ICMP_DEST_UNREACHABLE   0x03 /**< Destination Unreachable */
#define ICMP_SOURCE_QUENCH      0x04 /**< Source Quench */
#define ICMP_REDIR_MESSAGE      0x05 /**< Redirect Message */
#define ICMP_ALT_HOST_ADD       0x06 /**< Alternate Host Address */
/*  0x07 Reserved */
#define ICMP_ECHO_REQUEST       0x08 /**< Echo Request */
#define ICMP_ROUTER_ADV         0x09 /**< Router Advertisement */
#define ICMP_ROUTER_SOL         0x0A /**< Router Solicitation */
#define ICMP_TIME_EXC           0x0B /**< Time Exceeded */
#define ICMP_PARAM_PB           0x0C /**< Parameter Problem: Bad IP header */
#define ICMP_TIMESTAMP          0x0D /**< Timestamp */
#define ICMP_TIMESTAMP_REP      0x0E /**< Timestamp Reply */
#define ICMP_INFO_REQ           0x0F /**< Information Request */
#define ICMP_INFO_REPLY         0x10 /**< Information Reply */
#define ICMP_ADD_MASK_REQ       0x11 /**< Address Mask Request */
#define ICMP_ADD_MASK_REP       0x12 /**< Address Mask Reply */
/*  0x13 Reserved for security */
/*  0X14 through 0x1D Reserved for robustness experiment */
#define ICMP_TRACEROUTE         0x1E /**< Traceroute */
#define ICMP_DAT_CONV_ERROR     0x1F /**< Datagram Conversion Error */
#define ICMP_MOB_HOST_RED       0x20 /**< Mobile Host Redirect */
#define ICMP_W_A_Y              0x21 /**< Where-Are-You (originally meant for IPv6) */
#define ICMP_H_I_A              0x22 /**< Here-I-Am (originally meant for IPv6) */
#define ICMP_MOB_REG_REQ        0x23 /**< Mobile Registration Request */
#define ICMP_MOB_REG_REP        0x24 /**< Mobile Registration Reply */
#define ICMP_DOM_NAME_REQ       0x25 /**< Domain Name Request */
#define ICMP_DOM_NAME_REP       0x26 /**< Domain Name Reply */
#define ICMP_SKIP_ALGO_PROT     0x27 /**< SKIP Algorithm Discovery Protocol, Simple Key-Management for Internet Protocol */
#define ICMP_PHOTURIS           0x28 /**< Photuris, Security failures */
#define ICMP_EXP_MOBIL          0x29 /**< ICMP for experimental mobility protocols such as Seamoby [RFC4065] */
/* 0x2A through 0xFF Reserved */

/** Swap 2 bytes of a word */
#define SWAP16(x)   (((x & 0xff) << 8) | (x >> 8))

/** Ethernet header structure */
COMPILER_PACK_SET(1)
typedef struct ethernet_header {
	uint8_t et_dest[6];  /**< Destination node */
	uint8_t et_src[6];   /**< Source node */
	uint16_t et_protlen; /**< Protocol or length */
} ethernet_header_t, *p_ethernet_header_t;

/** ARP header structure */
COMPILER_PACK_SET(1)
typedef struct arp_header {
	uint16_t ar_hrd;   /**< Format of hardware address */
	uint16_t ar_pro;   /**< Format of protocol address */
	uint8_t ar_hln;    /**< Length of hardware address */
	uint8_t ar_pln;    /**< Length of protocol address */
	uint16_t ar_op;    /**< Operation */
	uint8_t ar_sha[6]; /**< Sender hardware address */
	uint8_t ar_spa[4]; /**< Sender protocol address */
	uint8_t ar_tha[6]; /**< Target hardware address */
	uint8_t ar_tpa[4]; /**< Target protocol address */
} arp_header_t, *p_arp_header_t;

/** IP Header structure */
COMPILER_PACK_SET(1)
typedef struct _IPheader {
	uint8_t ip_hl_v;   /**< Header length and version */
	uint8_t ip_tos;    /**< Type of service */
	uint16_t ip_len;   /**< Total length */
	uint16_t ip_id;    /**< Identification */
	uint16_t ip_off;   /**< Fragment offset field */
	uint8_t ip_ttl;    /**< Time to live */
	uint8_t ip_p;      /**< Protocol */
	uint16_t ip_sum;   /**< Checksum */
	uint8_t ip_src[4]; /**< Source IP address */
	uint8_t ip_dst[4]; /**< Destination IP address */
} ip_header_t, *p_ip_header_t;

/** ICMP echo header structure */
COMPILER_PACK_SET(1)
typedef struct icmp_echo_header {
	uint8_t type;   /**< Type of message */
	uint8_t code;   /**< Type subcode */
	uint16_t cksum; /**< 1's complement cksum of struct */
	uint16_t id;    /**< Identifier */
	uint16_t seq;   /**< Sequence number */
} icmp_echo_header_t, *p_icmp_echo_header_t;

/** Ethernet packet structure */
COMPILER_PACK_SET(1)
typedef struct eth_packet {
	ethernet_header_t eth_hdr;
	arp_header_t arp_hdr;
}  eth_packet_t, *p_eth_packet_t;

COMPILER_PACK_RESET()

/** Ethernet header size */
#define ETH_HEADER_SIZE   (sizeof(ethernet_header_t))

/** Ethernet IP header size */
#define ETH_IP_HEADER_SIZE   (sizeof(ip_header_t))

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, _4afc_ сказал:

У меня "Атмеловский". А что в ваших дампах много ещё отличий?

Не знал что Атмел разработал собственную доморощенную версию TCP/IP-протокола  :biggrin:

Как минимум "type of message" ICMP-кадра поменять с ECHO_REQUEST на ECHO_REPLY.

В 29.08.2022 в 17:10, yes сказал:

я очень приблизительно представляю как это делать - ну там адреса сорс/дестинэйшин поменять, тип пакета, таймштамп. CRC наверно нужно посчитать и т.д.

Обработка запрос-ответ на ICMP в моём стеке:

Спойлер
static u16 ipId = 0;

//ptr - ICMP-кадр; size - размер ICMP-кадра (с заголовком)
//return: аналогично ProcessEthFrame()
static int ProcessICMP(void const *ptr, u32 size)
{
  struct DataReqRep { //формат поля данных для типов: TYP_ECHO_REQUEST, TYP_ECHO_REPLY
    u16 id;   //идентификатор
    u16 seq;  //номер последовательности
  };
  enum {SIZE1 = sizeof(etx->head) + sizeof(etx->ip.head)};
  EthernetFrame *ptx;
  ICMPhead *p = (ICMPhead *)ptr;
  if (size < sizeof(*p) + sizeof(DataReqRep)) return 0;
  if (p->typ_code != ICMPhead::TYP_ECHO_REQUEST) return 0;
  #if !EMAC_CSUM_HW
  int j = p->csum;
  p->csum = 0;
  if (j -= Calc16Csum0(p, size)) return 0;
  #else //EMAC_CSUM_HW
  int j = 0;
  #endif //EMAC_CSUM_HW
  if (size > sizeof(eRAM.txBufSmall) - SIZE1) {
    if (size > sizeof(eRAM.txBufLarge) - SIZE1) return 0;
    j = 1;
  }
  EnetTProfileAdd(TP_ProcessICMP_DETECT_FRAME);
  if (!(ptx = EmacTxPrepare(j))) return -1;
  LogCR(COL_LIME "Incoming PING from " PRINT_IP_FMTL COL_BLACK " id=" COL_BLUE "%u"
    COL_BLACK " seqN=" COL_BLUE "%u" COL_BLACK " [%u]", PRINT_IP(erx->ip.head.srcIP),
    Rev16(((DataReqRep *)&p[1])->id), Rev16(((DataReqRep *)&p[1])->seq),
    size - sizeof(*p) - sizeof(DataReqRep));
  ptx->head.dstMAC.set(&erx->head.srcMAC);
  ptx->head.typ = SWAPB(EFRAME_IPv4);
  ptx->ip.head.ttl_prot = DEFAULT_TTL | IPhead::PROT_ICMP << 8;
  ptx->ip.head.dstIP = erx->ip.head.srcIP;
  ptx->ip.head.srcIP = erx->ip.head.dstIP;
  Fill2(size);
  ptx->ip.icmp.head.typ_code = ICMPhead::TYP_ECHO_REPLY;
  #if EMAC_CSUM_HW
  ptx->ip.icmp.head.csum = 0;
  #endif //EMAC_CSUM_HW
  memcpy16(&ptx->ip.icmp.data, &p[1], size - sizeof(*p)); //get data to echo
  AddCsum(&ptx->ip.icmp, size, &ptx->ip.icmp.head.csum);
  EmacTxSendTcpUdpIcmp(size + sizeof(ptx->head) + sizeof(ptx->ip.head));
  return 1;
}

static void Fill2(int size)
{
  EnetWriteWBE(&etx->ip.head.totalLen, size + sizeof(etx->ip.head));
  etx->ip.head.ver_ihl_tos_ecn = 0x40 | sizeof(etx->ip.head) + 3 >> 2;
  uint i = ++ipId;
  etx->ip.head.id = Rev16(i);
  etx->ip.head.flags_frag = IP_FLAG_DONTFRAG;
  AddCsum(&etx->ip.head, sizeof(etx->ip.head), &etx->ip.head.csum);
}

 

Формирование ответа в *ptx-кадре от исходного *prx-кадра начинается со строки ptx->head.dstMAC.set(&erx->head.srcMAC);

и далее до конца функции ProcessICMP()

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/30/2022 at 5:32 PM, jcxz said:

Не знал что Атмел разработал собственную доморощенную версию TCP/IP-протокола  :biggrin:

Только ICMP и UDP.

TCP я добавлял уже сам. Меня тоже посылали на всякие RFC и говорили что TCP это сложно.

По факту от UDP отличается добавлением двух 32х разрядных счётчиков и статуса есть или нет соединение...

 

On 8/30/2022 at 5:32 PM, jcxz said:

Как минимум "type of message" ICMP-кадра поменять с ECHO_REQUEST на ECHO_REPLY.

Обработка запрос-ответ на ICMP в моём стеке:

Ну да. Заработало?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, _4afc_ сказал:

По факту от UDP отличается добавлением двух 32х разрядных счётчиков и статуса есть или нет соединение...

Значит вы ничего не поняли в том как TCP работает. печально...  :unknw:

3 часа назад, _4afc_ сказал:

Ну да. Заработало?

Если бы не работало, зачем бы я выкладывал?  :wacko2:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...