original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
@@ -0,0 +1,587 @@
/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_pcap.c,v $ $Revision: 1.3.80.5 $
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_pcap.c,v $
* $Author: jsheng $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
* Writes all received and sent packets on a network interface to a pcap
* compatible file. The created file can be loaded into Wireshark, which
* in turn allows for analysis of the stream(s) send and received on the
* monitored network interface.
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
#include "ipnet_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef IPNET_USE_PCAP
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_file.h>
#include <ipcom_hash.h>
#include <ipcom_pkt.h>
#include <ipcom_syslog.h>
#include <ipcom_time.h>
#include "ipnet_pcap.h"
#include "ipnet_h.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPNET_PCAP_MAGIC 0xa1b2c3d4
#define IPNET_PCAP_MAGIC_SWAPPED 0xd4c3b2a1
#define IPNET_PCAP_VERSION_MAJOR 2
#define IPNET_PCAP_VERSION_MINOR 4
#define IPNET_PCAP_THISZONE 0
#define IPNET_PCAP_SIGFIGS 0
#define IPNET_PCAP_SNAPLEN 0xffff
#define IPNET_PCAP_NETWORK_80211 105
#define IPNET_PCAP_NETWORK_DEFAULT 101
#define IPNET_PCAP_NETWORK_ETHERNET 1
#define IPNET_PCAP_NETWORK_LOOP 101
#define IPNET_PCAP_NETWORK_PPP 9
/*
****************************************************************************
* 5
TYPES
****************************************************************************
*/
/* Global header for capture file */
typedef struct Ipnet_pcap_hdr_struct
{
Ip_u32 magic_number; /* magic number,
0xa1b2c3d4 -> all fields in correct byteorder
0xd4c3b2a1 -> all fields must be swapped */
Ip_u16 version_major; /* major version number */
Ip_u16 version_minor; /* minor version number */
Ip_s32 thiszone; /* GMT to local correction */
Ip_u32 sigfigs; /* accuracy of timestamps */
Ip_u32 snaplen; /* max length of captured packets, in octets */
Ip_u32 network; /* data link type, IPNET_PCAP_NETWORK_xxx */
}
Ipnet_pcap_hdr_t;
/* Header for every packet record */
typedef struct Ipnet_pcaprec_hdr_struct {
Ip_u32 ts_sec; /* timestamp seconds */
Ip_u32 ts_usec; /* timestamp microseconds */
Ip_u32 incl_len; /* number of octets of packet saved in file */
Ip_u32 orig_len; /* actual length of packet */
}
Ipnet_pcaprec_hdr_t;
/* Session stored in a file on the local filesystem */
typedef struct Ipnet_pcap_session_file_struct
{
char name[IPNET_PCAP_FNAMSIZ]; /* filename of the capture file */
}
Ipnet_pcap_session_file_t;
/* Session sent to a specific address & port */
typedef struct Ipnet_pcap_session_net_struct
{
int socket;
union Ip_sockaddr_union dst;
}
Ipnet_pcap_session_net_t;
struct Ipnet_pcap_session_struct;
typedef void (*Ipnet_pcap_add_record)(struct Ipnet_pcap_session_struct *session,
Ipcom_pkt *pkt);
typedef void (*Ipnet_pcap_dtor)(struct Ipnet_pcap_session_struct *session);
typedef struct Ipnet_pcap_session_struct
{
Ip_u32 ifindex; /* monitored network interface */
Ipnet_link_input link_input; /* original link_input handler for 'netif' */
Ipcom_drv_output drv_output; /* original drv_output handler for 'netif' */
Ipnet_pcap_dtor dtor; /* destructor for the session */
Ipnet_pcap_add_record add_record; /* session implementation for adding a record */
union {
Ipnet_pcap_session_file_t file;
Ipnet_pcap_session_net_t net;
} d;
}
Ipnet_pcap_session_t;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_STATIC Ipcom_hash *ipnet_pcap_sessions = IP_NULL;
/*
****************************************************************************
* 10 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipnet_pcap_session_key_func
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC unsigned
ipnet_pcap_session_key_func(Ip_u32 *ifindex)
{
return ipcom_hash_update(ifindex, sizeof(*ifindex), 0);
}
/*
*===========================================================================
* ipnet_pcap_session_obj_func
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC unsigned
ipnet_pcap_session_obj_func(Ipnet_pcap_session_t *session)
{
return ipnet_pcap_session_key_func(&session->ifindex);
}
/*
*===========================================================================
* ipnet_pcap_session_cmp_func
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_bool
ipnet_pcap_session_cmp_func(Ipnet_pcap_session_t *session, Ip_u32 *ifindex)
{
return session->ifindex == *ifindex;
}
/*
*===========================================================================
* ipnet_pcap_fill_header
*===========================================================================
* Description: Fills the fields of the global pcap header.
* Parameters: h - A pcap header buffer.
* Returns:
*
*/
IP_STATIC void
ipnet_pcap_fill_header(Ipnet_pcap_hdr_t *h, Ipnet_pcap_session_t *session)
{
Ipnet_netif *netif = ipnet_if_indextonetif(IPCOM_VR_ANY, session->ifindex);
if (netif == IP_NULL)
return;
h->magic_number = IPNET_PCAP_MAGIC;
h->version_major = IPNET_PCAP_VERSION_MAJOR;
h->version_minor = IPNET_PCAP_VERSION_MINOR;
h->thiszone = IPNET_PCAP_THISZONE;
h->sigfigs = IPNET_PCAP_SIGFIGS;
h->snaplen = IPNET_PCAP_SNAPLEN;
switch (netif->ipcom.type)
{
case IP_IFT_LOOP:
h->network = IPNET_PCAP_NETWORK_LOOP;
break;
case IP_IFT_ETHER:
case IP_IFT_L2VLAN:
h->network = IPNET_PCAP_NETWORK_ETHERNET;
break;
case IP_IFT_IEEE80211:
h->network = IPNET_PCAP_NETWORK_80211;
break;
case IP_IFT_PPP:
h->network = IPNET_PCAP_NETWORK_PPP;
break;
default:
h->network = IPNET_PCAP_NETWORK_DEFAULT;
break;
}
}
/*
*===========================================================================
* ipnet_pcap_new_record
*===========================================================================
* Description: Creates a new pcap record for a packet, the record must be
* freed with ipcom_free() by the caller.
* Parameters: pkt - The packet to add a record for.
* Returns: The new record or IP_NULL if out of memory.
*
*/
IP_STATIC Ipnet_pcaprec_hdr_t *
ipnet_pcap_new_record(Ipcom_pkt *pkt)
{
Ipnet_pcaprec_hdr_t *rec;
int pkt_len = ipcom_pkt_get_length(pkt);
rec = ipcom_malloc(sizeof(*rec) + pkt_len);
if (rec != IP_NULL)
{
struct Ip_timeval tv;
Ipcom_pkt *next_part = pkt;
int offset = 0;
Ip_u8 *data = (Ip_u8 *)(rec + 1);
(void)ipcom_gettimeofday(&tv, IP_NULL);
rec->ts_sec = (Ip_u32)tv.tv_sec;
rec->ts_usec = (Ip_u32)tv.tv_usec;
rec->incl_len = (Ip_u32) pkt_len;
rec->orig_len = (Ip_u32) pkt_len;
while (next_part != IP_NULL)
{
ipcom_memcpy(data + offset,
&next_part->data[next_part->start],
next_part->end - next_part->start);
offset += (next_part->end - next_part->start);
next_part = next_part->next_part;
}
}
return rec;
}
/*
*===========================================================================
* ipnet_pcap_file_add_record
*===========================================================================
* Description: Adds a pcap record by appending it to the file associated
* with the session.
* Parameters: session - A pcap file session.
* pkt - The packet to add a record for.
* Returns:
*
*/
IP_STATIC void
ipnet_pcap_file_add_record(Ipnet_pcap_session_t *session, Ipcom_pkt *pkt)
{
IP_FILE *f;
Ipnet_pcaprec_hdr_t *rec;
if (IP_NULL != (f = ipcom_fopen(session->d.file.name, "a")))
{
if (IP_NULL != (rec = ipnet_pcap_new_record(pkt)))
{
(void)ipcom_fwrite(rec, sizeof(*rec) + rec->incl_len, 1, f);
ipcom_free(rec);
}
ipcom_fclose(f);
}
}
/*
*===========================================================================
* ipnet_pcap_add_record
*===========================================================================
* Description: Adds a packet to the pcap backend storage.
* Parameters: netif - The network interface the packet was capture on.
* pkt - The packet to capture.
* Returns:
*
*/
IP_STATIC Ipnet_pcap_session_t *
ipnet_pcap_add_record(Ipcom_netif *netif,
Ipcom_pkt *pkt,
int pcap_dir,
Ip_u16 frame_type,
int mac,
int payload)
{
Ipnet_pcap_session_t *session;
(void) pcap_dir;
(void) frame_type;
(void) mac;
(void) payload;
session = ipcom_hash_get(ipnet_pcap_sessions, &netif->ifindex);
ip_assert(session != IP_NULL);
session->add_record(session, pkt);
return session;
}
/*
*===========================================================================
* ipnet_pcap_link_input
*===========================================================================
* Description:
* Parameters:
* Returns: 0 = success
* <0 = error code
*
*/
IP_STATIC int
ipnet_pcap_link_input(Ipnet_netif *netif, Ipcom_pkt *pkt)
{
return ipnet_pcap_add_record(&netif->ipcom, pkt, IP_PACKET_HOST, 0, -1, -1)->link_input(netif, pkt);
}
/*
*===========================================================================
* ipnet_pcap_drv_output
*===========================================================================
* Description:
* Parameters:
* Returns: 0 = success
* <0 = error code
*
*/
IP_STATIC int
ipnet_pcap_drv_output(Ipcom_netif *netif, Ipcom_pkt *pkt)
{
return ipnet_pcap_add_record(netif, pkt, IP_PACKET_OUTGOING, 0, -1, -1)->drv_output(netif, pkt);
}
/*
*===========================================================================
* ipnet_pcap_file_init
*===========================================================================
* Description: Adds a pcap record by appending it to the file associated
* with the session.
* Parameters: session - A pcap file session.
* pkt - The packet to add a record for.
* Returns: 0 = success
* <0 = error code
*
*/
IP_STATIC int
ipnet_pcap_file_init(Ipnet_pcap_session_t *session, const char *filename)
{
Ipnet_pcap_hdr_t hdr;
IP_FILE *f;
session->add_record = ipnet_pcap_file_add_record;
session->dtor = IP_NULL;
ipcom_strncpy(session->d.file.name, filename, IPNET_PCAP_FNAMSIZ);
session->d.file.name[IPNET_PCAP_FNAMSIZ-1] = '\0';
f = ipcom_fopen(filename, "w");
if (f == IP_NULL)
{
IPCOM_LOG2(ERR, "ipnet_pcap_file_init: failed to create file %s: %s",
filename,
ipcom_strerror(ipcom_errno));
return -ipcom_errno;
}
ipnet_pcap_fill_header(&hdr, session);
(void)ipcom_fwrite(&hdr, sizeof(hdr), 1, f);
ipcom_fclose(f);
return 0;
}
/*
*===========================================================================
* ipnet_pcap_net_init
*===========================================================================
* Description: Adds a pcap record by appending it to the file associated
* with the session.
* Parameters: session - A pcap file session.
* pkt - The packet to add a record for.
* Returns: 0 = success
* <0 = error code
*
*/
IP_STATIC int
ipnet_pcap_net_init(Ipnet_pcap_session_t *session, union Ip_sockaddr_union *dst)
{
IPCOM_UNUSED_ARG(session);
IPCOM_UNUSED_ARG(dst);
/* NOT IMPLEMENTED YET */
return -IP_ERRNO_ENOSYS;
}
/*
****************************************************************************
* 11 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipnet_pcap_ioctl
*===========================================================================
* Description:
* Parameters: session - A pcap file session.
* pkt - The packet to add a record for.
* Returns: 0 = success
<0 = error code
*
*/
IP_GLOBAL int
ipnet_pcap_ioctl(Ipnet_netif *netif, Ip_u32 command, void *data)
{
struct Ip_ifreq *ifreq = data;
Ipnet_pcap_ioctl_t *pcap = ifreq->ip_ifr_data;
Ipnet_pcap_session_t *session;
int ret = -IP_ERRNO_EINVAL;
(void) command;
ip_assert(command == IP_SIOCXPCAP);
if (pcap == IP_NULL)
return -IP_ERRNO_EINVAL;
if (ipnet_pcap_sessions == IP_NULL)
{
ipnet_pcap_sessions
= ipcom_hash_new((Ipcom_hash_obj_func) ipnet_pcap_session_key_func,
(Ipcom_hash_key_func) ipnet_pcap_session_obj_func,
(Ipcom_hash_cmp_func) ipnet_pcap_session_cmp_func);
}
session = ipcom_hash_get(ipnet_pcap_sessions, &netif->ipcom.ifindex);
switch (pcap->op)
{
case IPNET_PCAP_OP_START:
/* Enable capture */
if (session != IP_NULL)
return -IP_ERRNO_EEXIST;
session = ipcom_calloc(1, sizeof(*session));
if (session == IP_NULL)
return -IP_ERRNO_ENOMEM;
session->ifindex = netif->ipcom.ifindex;
if (ipcom_hash_add(ipnet_pcap_sessions, session) != IPCOM_SUCCESS)
{
ipcom_free(session);
return -IP_ERRNO_ENOMEM;
}
switch (pcap->type)
{
case IPNET_PCAP_TYPE_FILE:
ret = ipnet_pcap_file_init(session, pcap->d.filename);
break;
case IPNET_PCAP_TYPE_NET:
ret = ipnet_pcap_net_init(session, &pcap->d.dst);
break;
default:
break;
}
if (ret != 0)
{
(void)ipcom_hash_remove(ipnet_pcap_sessions, session);
ipcom_free(session);
}
else
{
session->link_input = netif->link_input;
session->drv_output = netif->ipcom.drv_output;
switch (netif->ipcom.type)
{
case IP_IFT_LOOP:
netif->ipcom.drv_output = ipnet_pcap_drv_output;
break;
case IP_IFT_L2VLAN:
case IP_IFT_TUNNEL:
netif->ipcom.link_tap = (Ipcom_link_tap) ipnet_pcap_add_record;
break;
default:
netif->link_input = ipnet_pcap_link_input;
netif->ipcom.drv_output = ipnet_pcap_drv_output;
break;
}
}
break;
case IPNET_PCAP_OP_STOP:
/* Disable capture */
if (session == IP_NULL)
return -IP_ERRNO_ENOENT;
if (ipcom_hash_remove(ipnet_pcap_sessions, session) != IPCOM_SUCCESS)
IP_PANIC();
if (session->dtor != IP_NULL)
session->dtor(session);
netif->link_input = session->link_input;
netif->ipcom.drv_output = session->drv_output;
netif->ipcom.link_tap = IP_NULL;
ipcom_free(session);
ret = 0;
break;
default:
break;
}
return ret;
}
#endif /* IPNET_USE_PCAP */