[PATCH] s390: introduce guestLan sniffer support in qeth
[patch 6/7] s390: introduce guestLan sniffer support in qeth From: Peter Tiedemann <ptiedem@de.ibm.com> - introduce guestLan sniffer support in qeth feature allows a linux in a virtual machine guest to become a network LAN sniffer, monitoring and recording the networking traffic within an entire guestLan. Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com> diffstat: qeth.h | 2 + qeth_main.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qeth_mpc.h | 11 ++++--- 3 files changed, 102 insertions(+), 4 deletions(-) Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
committed by
Jeff Garzik
parent
e08d88cccb
commit
6c951b9051
@@ -750,6 +750,7 @@ struct qeth_card_info {
|
|||||||
int unique_id;
|
int unique_id;
|
||||||
struct qeth_card_blkt blkt;
|
struct qeth_card_blkt blkt;
|
||||||
__u32 csum_mask;
|
__u32 csum_mask;
|
||||||
|
enum qeth_ipa_promisc_modes promisc_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qeth_card_options {
|
struct qeth_card_options {
|
||||||
@@ -776,6 +777,7 @@ struct qeth_card_options {
|
|||||||
enum qeth_threads {
|
enum qeth_threads {
|
||||||
QETH_SET_IP_THREAD = 1,
|
QETH_SET_IP_THREAD = 1,
|
||||||
QETH_RECOVER_THREAD = 2,
|
QETH_RECOVER_THREAD = 2,
|
||||||
|
QETH_SET_PROMISC_MODE_THREAD = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qeth_osn_info {
|
struct qeth_osn_info {
|
||||||
|
@@ -159,6 +159,9 @@ qeth_get_addr_buffer(enum qeth_prot_versions);
|
|||||||
static void
|
static void
|
||||||
qeth_set_multicast_list(struct net_device *);
|
qeth_set_multicast_list(struct net_device *);
|
||||||
|
|
||||||
|
static void
|
||||||
|
qeth_setadp_promisc_mode(struct qeth_card *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qeth_notify_processes(void)
|
qeth_notify_processes(void)
|
||||||
{
|
{
|
||||||
@@ -965,6 +968,24 @@ qeth_register_ip_addresses(void *ptr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drive the SET_PROMISC_MODE thread
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qeth_set_promisc_mode(void *ptr)
|
||||||
|
{
|
||||||
|
struct qeth_card *card = (struct qeth_card *) ptr;
|
||||||
|
|
||||||
|
daemonize("qeth_setprm");
|
||||||
|
QETH_DBF_TEXT(trace,4,"setprm1");
|
||||||
|
if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD))
|
||||||
|
return 0;
|
||||||
|
QETH_DBF_TEXT(trace,4,"setprm2");
|
||||||
|
qeth_setadp_promisc_mode(card);
|
||||||
|
qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qeth_recover(void *ptr)
|
qeth_recover(void *ptr)
|
||||||
{
|
{
|
||||||
@@ -1031,6 +1052,8 @@ qeth_start_kernel_thread(struct qeth_card *card)
|
|||||||
|
|
||||||
if (qeth_do_start_thread(card, QETH_SET_IP_THREAD))
|
if (qeth_do_start_thread(card, QETH_SET_IP_THREAD))
|
||||||
kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD);
|
kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD);
|
||||||
|
if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD))
|
||||||
|
kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD);
|
||||||
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
|
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
|
||||||
kernel_thread(qeth_recover, (void *) card, SIGCHLD);
|
kernel_thread(qeth_recover, (void *) card, SIGCHLD);
|
||||||
}
|
}
|
||||||
@@ -5003,6 +5026,10 @@ qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *,
|
|||||||
unsigned long);
|
unsigned long);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
qeth_default_setadapterparms_cb(struct qeth_card *card,
|
||||||
|
struct qeth_reply *reply,
|
||||||
|
unsigned long data);
|
||||||
|
static int
|
||||||
qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,
|
qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,
|
||||||
__u16, long,
|
__u16, long,
|
||||||
int (*reply_cb)
|
int (*reply_cb)
|
||||||
@@ -5476,6 +5503,59 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
|
|||||||
qeth_set_multicast_list(card->dev);
|
qeth_set_multicast_list(card->dev);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/**
|
||||||
|
* Examine hardware response to SET_PROMISC_MODE
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qeth_setadp_promisc_mode_cb(struct qeth_card *card,
|
||||||
|
struct qeth_reply *reply,
|
||||||
|
unsigned long data)
|
||||||
|
{
|
||||||
|
struct qeth_ipa_cmd *cmd;
|
||||||
|
struct qeth_ipacmd_setadpparms *setparms;
|
||||||
|
|
||||||
|
QETH_DBF_TEXT(trace,4,"prmadpcb");
|
||||||
|
|
||||||
|
cmd = (struct qeth_ipa_cmd *) data;
|
||||||
|
setparms = &(cmd->data.setadapterparms);
|
||||||
|
|
||||||
|
qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
|
||||||
|
if (cmd->hdr.return_code) {
|
||||||
|
QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
|
||||||
|
setparms->data.mode = SET_PROMISC_MODE_OFF;
|
||||||
|
}
|
||||||
|
card->info.promisc_mode = setparms->data.mode;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Set promiscuous mode (on or off) (SET_PROMISC_MODE command)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
qeth_setadp_promisc_mode(struct qeth_card *card)
|
||||||
|
{
|
||||||
|
enum qeth_ipa_promisc_modes mode;
|
||||||
|
struct net_device *dev = card->dev;
|
||||||
|
struct qeth_cmd_buffer *iob;
|
||||||
|
struct qeth_ipa_cmd *cmd;
|
||||||
|
|
||||||
|
QETH_DBF_TEXT(trace, 4, "setprom");
|
||||||
|
|
||||||
|
if (((dev->flags & IFF_PROMISC) &&
|
||||||
|
(card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
|
||||||
|
(!(dev->flags & IFF_PROMISC) &&
|
||||||
|
(card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
|
||||||
|
return;
|
||||||
|
mode = SET_PROMISC_MODE_OFF;
|
||||||
|
if (dev->flags & IFF_PROMISC)
|
||||||
|
mode = SET_PROMISC_MODE_ON;
|
||||||
|
QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);
|
||||||
|
|
||||||
|
iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
|
||||||
|
sizeof(struct qeth_ipacmd_setadpparms));
|
||||||
|
cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
|
||||||
|
cmd->data.setadapterparms.data.mode = mode;
|
||||||
|
qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set multicast address on card
|
* set multicast address on card
|
||||||
@@ -5501,6 +5581,11 @@ qeth_set_multicast_list(struct net_device *dev)
|
|||||||
out:
|
out:
|
||||||
if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
|
if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
|
||||||
schedule_work(&card->kernel_thread_starter);
|
schedule_work(&card->kernel_thread_starter);
|
||||||
|
if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
|
||||||
|
return;
|
||||||
|
if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0)
|
||||||
|
schedule_work(&card->kernel_thread_starter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -6510,6 +6595,8 @@ qeth_default_setadapterparms_cb(struct qeth_card *card,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,
|
qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,
|
||||||
unsigned long data)
|
unsigned long data)
|
||||||
@@ -6676,6 +6763,12 @@ qeth_layer2_initialize(struct qeth_card *card)
|
|||||||
QETH_DBF_TEXT(setup, 2, "doL2init");
|
QETH_DBF_TEXT(setup, 2, "doL2init");
|
||||||
QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));
|
QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));
|
||||||
|
|
||||||
|
rc = qeth_query_setadapterparms(card);
|
||||||
|
if (rc) {
|
||||||
|
PRINT_WARN("could not query adapter parameters on device %s: "
|
||||||
|
"x%x\n", CARD_BUS_ID(card), rc);
|
||||||
|
}
|
||||||
|
|
||||||
rc = qeth_setadpparms_change_macaddr(card);
|
rc = qeth_setadpparms_change_macaddr(card);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
PRINT_WARN("couldn't get MAC address on "
|
PRINT_WARN("couldn't get MAC address on "
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include <asm/qeth.h>
|
#include <asm/qeth.h>
|
||||||
|
|
||||||
#define VERSION_QETH_MPC_H "$Revision: 1.43 $"
|
#define VERSION_QETH_MPC_H "$Revision: 1.44 $"
|
||||||
|
|
||||||
extern const char *VERSION_QETH_MPC_C;
|
extern const char *VERSION_QETH_MPC_C;
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ enum qeth_ipa_setadp_cmd {
|
|||||||
IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
|
IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
|
||||||
IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
|
IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
|
||||||
IPA_SETADP_READ_SNMP_PARMS = 0x0400,
|
IPA_SETADP_READ_SNMP_PARMS = 0x0400,
|
||||||
IPA_SETADP_WRITE_SNMP_PARMS = 0x0800,
|
IPA_SETADP_SET_PROMISC_MODE = 0x0800,
|
||||||
IPA_SETADP_QUERY_CARD_INFO = 0x1000,
|
IPA_SETADP_QUERY_CARD_INFO = 0x1000,
|
||||||
};
|
};
|
||||||
enum qeth_ipa_mac_ops {
|
enum qeth_ipa_mac_ops {
|
||||||
@@ -232,9 +232,12 @@ enum qeth_ipa_addr_ops {
|
|||||||
CHANGE_ADDR_ADD_ADDR = 1,
|
CHANGE_ADDR_ADD_ADDR = 1,
|
||||||
CHANGE_ADDR_DEL_ADDR = 2,
|
CHANGE_ADDR_DEL_ADDR = 2,
|
||||||
CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
|
CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
enum qeth_ipa_promisc_modes {
|
||||||
|
SET_PROMISC_MODE_OFF = 0,
|
||||||
|
SET_PROMISC_MODE_ON = 1,
|
||||||
|
};
|
||||||
|
|
||||||
/* (SET)DELIP(M) IPA stuff ***************************************************/
|
/* (SET)DELIP(M) IPA stuff ***************************************************/
|
||||||
struct qeth_ipacmd_setdelip4 {
|
struct qeth_ipacmd_setdelip4 {
|
||||||
__u8 ip_addr[4];
|
__u8 ip_addr[4];
|
||||||
|
Reference in New Issue
Block a user