First lines of experimental pcap output support
This will serve to debug packets right under wireshark !
Этот коммит содержится в:
родитель
10f27457d3
Коммит
10b625e180
@ -6,3 +6,4 @@ option(WITH_STATIC_LIB "Build with a static library" OFF)
|
|||||||
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
|
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
|
||||||
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
|
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
|
||||||
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
|
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
|
||||||
|
option(WITH_PCAP "Compile with Pcap generation support" OFF)
|
||||||
|
@ -83,6 +83,9 @@
|
|||||||
/* Define to 1 if you want to enable debug output for crypto functions */
|
/* Define to 1 if you want to enable debug output for crypto functions */
|
||||||
#cmakedefine DEBUG_CRYPTO 1
|
#cmakedefine DEBUG_CRYPTO 1
|
||||||
|
|
||||||
|
/* Define to 1 if you want to enable pcap output support (experimental) */
|
||||||
|
#cmakedefine WITH_PCAP 1
|
||||||
|
|
||||||
/* Define to 1 if you want to enable calltrace debug output */
|
/* Define to 1 if you want to enable calltrace debug output */
|
||||||
#cmakedefine DEBUG_CALLTRACE 1
|
#cmakedefine DEBUG_CALLTRACE 1
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ struct ssh_buffer_struct {
|
|||||||
|
|
||||||
int buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
|
int buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
|
||||||
int buffer_add_u8(ssh_buffer buffer, uint8_t data);
|
int buffer_add_u8(ssh_buffer buffer, uint8_t data);
|
||||||
|
int buffer_add_u16(ssh_buffer buffer, uint16_t data);
|
||||||
int buffer_add_u32(ssh_buffer buffer, uint32_t data);
|
int buffer_add_u32(ssh_buffer buffer, uint32_t data);
|
||||||
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
|
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
|
||||||
int buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
|
int buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||||
|
30
include/libssh/pcap.h
Обычный файл
30
include/libssh/pcap.h
Обычный файл
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef PCAP_H_
|
||||||
|
#define PCAP_H_
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
typedef struct ssh_pcap_context_struct* ssh_pcap_context;
|
||||||
|
typedef struct ssh_pcap_file_struct* ssh_pcap_file;
|
||||||
|
|
||||||
|
ssh_pcap_file ssh_pcap_file_new(void);
|
||||||
|
int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
|
||||||
|
int ssh_pcap_file_close(ssh_pcap_file pcap);
|
||||||
|
void ssh_pcap_free(ssh_pcap_file pcap);
|
||||||
|
|
||||||
|
/* to be removed from here after tests */
|
||||||
|
int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, u_int32_t original_len);
|
||||||
|
|
||||||
|
ssh_pcap_context ssh_pcap_context_new(ssh_session session);
|
||||||
|
|
||||||
|
enum ssh_pcap_direction{
|
||||||
|
SSH_PCAP_DIR_IN,
|
||||||
|
SSH_PCAP_DIR_OUT
|
||||||
|
};
|
||||||
|
void ssh_pcap_context_set_file(ssh_pcap_context, ssh_pcap_file);
|
||||||
|
int ssh_pcap_context_write(ssh_pcap_context,enum ssh_pcap_direction direction, void *data,
|
||||||
|
u_int32_t len, u_int32_t origlen);
|
||||||
|
|
||||||
|
#endif /* WITH_PCAP */
|
||||||
|
#endif /* PCAP_H_ */
|
||||||
|
/* vim: set ts=2 sw=2 et cindent: */
|
@ -93,6 +93,7 @@ set(libssh_SRCS
|
|||||||
misc.c
|
misc.c
|
||||||
options.c
|
options.c
|
||||||
packet.c
|
packet.c
|
||||||
|
pcap.c
|
||||||
poll.c
|
poll.c
|
||||||
session.c
|
session.c
|
||||||
scp.c
|
scp.c
|
||||||
|
@ -174,6 +174,7 @@ int buffer_add_ssh_string(struct ssh_buffer_struct *buffer,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief add a 32 bits unsigned integer to the tail of buffer
|
* \brief add a 32 bits unsigned integer to the tail of buffer
|
||||||
* \param buffer buffer
|
* \param buffer buffer
|
||||||
@ -188,6 +189,20 @@ int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* \brief add a 16 bits unsigned integer to the tail of buffer
|
||||||
|
* \param buffer buffer
|
||||||
|
* \param data 16 bits integer
|
||||||
|
* \return 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
|
int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data){
|
||||||
|
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief add a 64 bits unsigned integer to the tail of buffer
|
* \brief add a 64 bits unsigned integer to the tail of buffer
|
||||||
* \param buffer buffer
|
* \param buffer buffer
|
||||||
|
291
libssh/pcap.c
Обычный файл
291
libssh/pcap.c
Обычный файл
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 by Aris Adamantiadis
|
||||||
|
*
|
||||||
|
* The SSH Library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* The SSH Library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with the SSH Library; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* pcap.c */
|
||||||
|
/** \defgroup ssh_pcap SSH-pcap
|
||||||
|
* \brief libssh pcap file generation
|
||||||
|
*
|
||||||
|
* \addtogroup ssh_pcap
|
||||||
|
* @{ */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "libssh/libssh.h"
|
||||||
|
#include "libssh/pcap.h"
|
||||||
|
#include "libssh/session.h"
|
||||||
|
#include "libssh/buffer.h"
|
||||||
|
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
/* The header of a pcap file is the following. We are not going to make it
|
||||||
|
* very complicated.
|
||||||
|
* Just for information.
|
||||||
|
*/
|
||||||
|
struct pcap_hdr_s {
|
||||||
|
u_int32_t magic_number; /* magic number */
|
||||||
|
u_int16_t version_major; /* major version number */
|
||||||
|
u_int16_t version_minor; /* minor version number */
|
||||||
|
int32_t thiszone; /* GMT to local correction */
|
||||||
|
u_int32_t sigfigs; /* accuracy of timestamps */
|
||||||
|
u_int32_t snaplen; /* max length of captured packets, in octets */
|
||||||
|
u_int32_t network; /* data link type */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PCAP_MAGIC 0xa1b2c3d4
|
||||||
|
#define PCAP_VERSION_MAJOR 2
|
||||||
|
#define PCAP_VERSION_MINOR 4
|
||||||
|
|
||||||
|
#define DLT_RAW 12 /* raw IP */
|
||||||
|
|
||||||
|
/* TCP flags */
|
||||||
|
#define TH_FIN 0x01
|
||||||
|
#define TH_SYN 0x02
|
||||||
|
#define TH_RST 0x04
|
||||||
|
#define TH_PUSH 0x08
|
||||||
|
#define TH_ACK 0x10
|
||||||
|
#define TH_URG 0x20
|
||||||
|
|
||||||
|
/* The header of a pcap packet.
|
||||||
|
* Just for information.
|
||||||
|
*/
|
||||||
|
struct pcaprec_hdr_s {
|
||||||
|
u_int32_t ts_sec; /* timestamp seconds */
|
||||||
|
u_int32_t ts_usec; /* timestamp microseconds */
|
||||||
|
u_int32_t incl_len; /* number of octets of packet saved in file */
|
||||||
|
u_int32_t orig_len; /* actual length of packet */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @private
|
||||||
|
* @brief a pcap context expresses the state of a pcap dump
|
||||||
|
* in a SSH session only. Multiple pcap contexts may be used into
|
||||||
|
* a single pcap file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ssh_pcap_context_struct {
|
||||||
|
ssh_session session;
|
||||||
|
ssh_pcap_file file;
|
||||||
|
/* All of these informations are useful to generate
|
||||||
|
* the dummy IP and TCP packets
|
||||||
|
*/
|
||||||
|
u_int32_t ipsource;
|
||||||
|
u_int32_t ipdest;
|
||||||
|
u_int16_t portsource;
|
||||||
|
u_int16_t portdest;
|
||||||
|
u_int32_t outsequence;
|
||||||
|
u_int32_t insequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @private
|
||||||
|
* @brief a pcap file expresses the state of a pcap file which may
|
||||||
|
* contain several streams.
|
||||||
|
*/
|
||||||
|
struct ssh_pcap_file_struct {
|
||||||
|
FILE *output;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief create a new ssh_pcap_file object
|
||||||
|
*/
|
||||||
|
ssh_pcap_file ssh_pcap_file_new(){
|
||||||
|
return malloc(sizeof(struct ssh_pcap_file_struct));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief writes a packet on file
|
||||||
|
*/
|
||||||
|
static int ssh_pcap_file_write(ssh_pcap_file pcap, ssh_buffer packet){
|
||||||
|
int err;
|
||||||
|
uint32_t len;
|
||||||
|
if(pcap == NULL || pcap->output==NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
len=buffer_get_len(packet);
|
||||||
|
err=fwrite(buffer_get(packet),len,1,pcap->output);
|
||||||
|
if(err<0)
|
||||||
|
return SSH_ERROR;
|
||||||
|
else
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief prepends a packet with the pcap header and writes packet
|
||||||
|
* on file
|
||||||
|
*/
|
||||||
|
int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, u_int32_t original_len){
|
||||||
|
ssh_buffer header=buffer_new();
|
||||||
|
struct timeval now;
|
||||||
|
int err;
|
||||||
|
if(header == NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
gettimeofday(&now,NULL);
|
||||||
|
buffer_add_u32(header,htonl(now.tv_sec));
|
||||||
|
buffer_add_u32(header,htonl(now.tv_usec));
|
||||||
|
buffer_add_u32(header,htonl(buffer_get_len(packet)));
|
||||||
|
buffer_add_u32(header,htonl(original_len));
|
||||||
|
buffer_add_buffer(header,packet);
|
||||||
|
err=ssh_pcap_file_write(pcap,header);
|
||||||
|
buffer_free(header);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief opens a new pcap file and create header
|
||||||
|
*/
|
||||||
|
int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename){
|
||||||
|
ssh_buffer header;
|
||||||
|
int err;
|
||||||
|
if(pcap == NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
if(pcap->output){
|
||||||
|
fclose(pcap->output);
|
||||||
|
pcap->output=NULL;
|
||||||
|
}
|
||||||
|
pcap->output=fopen(filename,"wb");
|
||||||
|
if(pcap->output==NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
header=buffer_new();
|
||||||
|
if(header==NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
buffer_add_u32(header,htonl(PCAP_MAGIC));
|
||||||
|
buffer_add_u16(header,htons(PCAP_VERSION_MAJOR));
|
||||||
|
buffer_add_u16(header,htons(PCAP_VERSION_MINOR));
|
||||||
|
/* currently hardcode GMT to 0 */
|
||||||
|
buffer_add_u32(header,htonl(0));
|
||||||
|
/* accuracy */
|
||||||
|
buffer_add_u32(header,htonl(0));
|
||||||
|
/* size of the biggest packet */
|
||||||
|
buffer_add_u32(header,htonl(MAX_PACKET_LEN));
|
||||||
|
/* we will write sort-of IP */
|
||||||
|
buffer_add_u32(header,htonl(DLT_RAW));
|
||||||
|
err=ssh_pcap_file_write(pcap,header);
|
||||||
|
buffer_free(header);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssh_pcap_file_close(ssh_pcap_file pcap){
|
||||||
|
int err;
|
||||||
|
if(pcap ==NULL || pcap->output==NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
err=fclose(pcap->output);
|
||||||
|
pcap->output=NULL;
|
||||||
|
if(err != 0)
|
||||||
|
return SSH_ERROR;
|
||||||
|
else
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssh_pcap_free(ssh_pcap_file pcap){
|
||||||
|
ssh_pcap_file_close(pcap);
|
||||||
|
SAFE_FREE(pcap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief allocates a new ssh_pcap_context object
|
||||||
|
*/
|
||||||
|
|
||||||
|
ssh_pcap_context ssh_pcap_context_new(ssh_session session){
|
||||||
|
ssh_pcap_context ctx=malloc(sizeof(struct ssh_pcap_context_struct));
|
||||||
|
if(ctx==NULL){
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ZERO_STRUCTP(ctx);
|
||||||
|
ctx->session=session;
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssh_pcap_context_set_file(ssh_pcap_context ctx, ssh_pcap_file pcap){
|
||||||
|
ctx->file=pcap;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssh_pcap_context_write(ssh_pcap_context ctx,enum ssh_pcap_direction direction
|
||||||
|
, void *data, u_int32_t len, u_int32_t origlen){
|
||||||
|
ssh_buffer ip=buffer_new();
|
||||||
|
int err;
|
||||||
|
if(ip==NULL){
|
||||||
|
ssh_set_error_oom(ctx->session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
/* build an IP packet */
|
||||||
|
/* V4, 20 bytes */
|
||||||
|
buffer_add_u8(ip,4 << 4 | 5);
|
||||||
|
/* tos */
|
||||||
|
buffer_add_u8(ip,0);
|
||||||
|
/* total len */
|
||||||
|
buffer_add_u16(ip,htons(origlen + 40));
|
||||||
|
/* id */
|
||||||
|
buffer_add_u16(ip,htons(1));
|
||||||
|
/* fragment offset */
|
||||||
|
buffer_add_u16(ip,htons(0));
|
||||||
|
/* TTL */
|
||||||
|
buffer_add_u8(ip,64);
|
||||||
|
/* protocol TCP=6 */
|
||||||
|
buffer_add_u8(ip,6);
|
||||||
|
/* checksum */
|
||||||
|
buffer_add_u16(ip,0);
|
||||||
|
if(direction==SSH_PCAP_DIR_OUT){
|
||||||
|
buffer_add_u32(ip,ctx->ipsource);
|
||||||
|
buffer_add_u32(ip,ctx->ipdest);
|
||||||
|
} else {
|
||||||
|
buffer_add_u32(ip,ctx->ipdest);
|
||||||
|
buffer_add_u32(ip,ctx->ipsource);
|
||||||
|
}
|
||||||
|
/* TCP */
|
||||||
|
if(direction==SSH_PCAP_DIR_OUT){
|
||||||
|
buffer_add_u16(ip,ntohs(ctx->portsource));
|
||||||
|
buffer_add_u16(ip,ntohs(ctx->portdest));
|
||||||
|
} else {
|
||||||
|
buffer_add_u16(ip,ntohs(ctx->portdest));
|
||||||
|
buffer_add_u16(ip,ntohs(ctx->portsource));
|
||||||
|
}
|
||||||
|
/* sequence number */
|
||||||
|
if(direction==SSH_PCAP_DIR_OUT){
|
||||||
|
buffer_add_u32(ip,ntohl(ctx->outsequence));
|
||||||
|
} else {
|
||||||
|
buffer_add_u32(ip,ntohl(ctx->insequence));
|
||||||
|
}
|
||||||
|
/* ack number */
|
||||||
|
if(direction==SSH_PCAP_DIR_OUT){
|
||||||
|
buffer_add_u32(ip,ntohl(ctx->insequence));
|
||||||
|
} else {
|
||||||
|
buffer_add_u32(ip,ntohl(ctx->outsequence));
|
||||||
|
}
|
||||||
|
/* header len */
|
||||||
|
buffer_add_u8(ip,5 << 4);
|
||||||
|
/* flags */
|
||||||
|
buffer_add_u8(ip,TH_PUSH | TH_ACK);
|
||||||
|
/* window */
|
||||||
|
buffer_add_u16(ip,htons(65535));
|
||||||
|
/* checksum */
|
||||||
|
buffer_add_u16(ip,htons(0));
|
||||||
|
/* urgent data ptr */
|
||||||
|
buffer_add_u16(ip,0);
|
||||||
|
/* actual data */
|
||||||
|
buffer_add_data(ip,data,len);
|
||||||
|
err=ssh_pcap_file_write_packet(ctx->file,ip,origlen + 40);
|
||||||
|
buffer_free(ip);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WITH_PCAP */
|
||||||
|
/** @} */
|
||||||
|
/* vim: set ts=2 sw=2 et cindent: */
|
@ -1,4 +1,4 @@
|
|||||||
all: test_tunnel test_exec
|
all: test_tunnel test_exec test_pcap
|
||||||
CFLAGS=-I../include/ -g -Wall
|
CFLAGS=-I../include/ -g -Wall
|
||||||
LDFLAGS=-lssh -L../build/libssh/
|
LDFLAGS=-lssh -L../build/libssh/
|
||||||
|
|
||||||
@ -8,5 +8,8 @@ test_tunnel: test_tunnel.o authentication.o connection.o
|
|||||||
test_exec: test_exec.o authentication.o connection.o
|
test_exec: test_exec.o authentication.o connection.o
|
||||||
gcc -o $@ $^ $(LDFLAGS)
|
gcc -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
test_pcap: test_pcap.o
|
||||||
|
gcc -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o test_tunnel
|
rm -f *.o test_tunnel
|
||||||
|
50
tests/test_pcap.c
Обычный файл
50
tests/test_pcap.c
Обычный файл
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 by Aris Adamantiadis
|
||||||
|
*
|
||||||
|
* The SSH Library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* The SSH Library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with the SSH Library; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Simple test for the pcap functions */
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <libssh/pcap.h>
|
||||||
|
#include <libssh/buffer.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
ssh_pcap_file pcap;
|
||||||
|
ssh_pcap_context ctx;
|
||||||
|
ssh_buffer buffer=buffer_new();
|
||||||
|
char *str="Hello, this is a test string to test the capabilities of the"
|
||||||
|
"pcap file writer.";
|
||||||
|
printf("Simple pcap tester\n");
|
||||||
|
pcap=ssh_pcap_file_new();
|
||||||
|
if(ssh_pcap_file_open(pcap,"test.cap") != SSH_OK){
|
||||||
|
printf("error happened\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
buffer_add_data(buffer,str,strlen(str));
|
||||||
|
ctx=ssh_pcap_context_new(NULL);
|
||||||
|
ssh_pcap_context_set_file(ctx,pcap);
|
||||||
|
ssh_pcap_context_write(ctx,SSH_PCAP_DIR_OUT,str,strlen(str),strlen(str));
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче
Block a user