mac address order - mac-address

I found out MAC address of my net device in ifconfig -a - HWaddr 00:1a:92:9c:9b:bb
How can I relate to this address in my code?
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
__be16 h_proto; /* packet type ID field */
} __attribute__((packed));
I'm endeavouring to write to h_dest
memcpy(eth->h_dest,dest_mac,ETH_ALEN);
but I do not know in what order of bytes and bites must I pass the MAC-address value.

They should be in left-to-right order, so h_dest[0] = 0x00.

Related

Why is stat's st_size field offset 96 on 64bit OSX and can it be calculated?

Using the latest sources from apple's open source repo I have derived the following structure for the "stat" struct (in go syntax):
type timespec struct {
tv_sec int32
tv_nsec uint32
}
type stat64 struct {
st_dev int32 /* [XSI] ID of device containing file */
st_mode uint16 /* [XSI] Mode of file (see below) */
st_nlink uint16 /* [XSI] Number of hard links */
st_ino uint64 /* [XSI] File serial number */
st_uid uint32 /* [XSI] User ID of the file */
st_gid uint32 /* [XSI] Group ID of the file */
st_rdev int32 /* [XSI] Device ID */
st_atimespec timespec /* time of last access */
st_mtimespec timespec /* time of last data modification */
st_ctimespec timespec /* time of last status change */
st_birthtimespec timespec /* time of file creation(birth) */
st_size int64 /* [XSI] file size, in bytes */
st_blocks int64 /* [XSI] blocks allocated for file */
st_blksize int32 /* [XSI] optimal blocksize for I/O */
st_flags uint32 /* user defined flags for file */
st_gen uint32 /* file generation number */
st_lspare int32 /* RESERVED: DO NOT USE! */
st_qspare [2]int64 /* RESERVED: DO NOT USE! */
}
but in practice it turns out st_size has an offset of 96 bytes instead of the 60 shown above. What's the cause of this discrepancy and how can this be seen from the original source code?
On OS X, both fields of struct timespec are long, which is 64-bit in the usual LP64 convention. Therefore, sizeof(struct timespec) == 16 (you can check this yourself), and it is aligned on a 64-bit boundary, giving you an offset of 96 for st_size.

Trouble capturing IP packets with libpcap

First the structs:
/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN 6
/* Ethernet header */
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
#define ETHERTYPE_IP 0x0800 /* IP */
/* IP header */
struct sniff_ip {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
I have opened the network device with pcap_open_live, the pcap_datalink is DLT_EN10MB for that device, but I am receiving lots of IP headers with 0 length, weird version number, etc.
Here's a snippet that outputs this:
eth = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(eth + 14); /* ETHERNET = 14 */
int version_ip = IP_V(ip);
int size_ip = IP_HL(ip)*4;
printf("caplen=%d len=%d eth->type=%d version_ip=%d size_ip=%d !\n", header.caplen, header.len, eth->ether_type, version_ip, size_ip);
And some sample output:
caplen=94 len=94 eth->type=8 version_ip=0 size_ip=0 !
caplen=159 len=159 eth->type=8 version_ip=9 size_ip=12 !
caplen=110 len=110 eth->type=8 version_ip=0 size_ip=12 !
caplen=200 len=336 eth->type=8 version_ip=4 size_ip=20 ! (this one is OK)
What is going on here?
Why is eth type 0x0008 and not 0x0800? Endianness?
What's up with the weird ip header versions?
How can the IP header length be below 20 bytes?
Found the problem...
eth = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(eth + 14); /* should be (packet + 14) */
The 'smart' C pointer arithmetics doesn't add 14 bytes, but 14*sizeof(struct sniff_ethernet).

SCSI Inquiry Data

I am new to SCSI Programming and hence sorry for asking basic question. I sent SCSI Inquiry command to a Tape Device through 6 byte CDB
ccb = (Exec_IO_CCB *)( buffer + header_size );
ccb->ccb_length = sizeof(Exec_IO_CCB);
ccb->cam_opcode = 0x1;
ccb->connect_id = 0;
ccb->sense_buf_ptr = (long)(header_size + ccb->ccb_length);
ccb->sense_buf_length = MAX_SENSE_LEN;
ccb->time_out = CAM_TIMEOUT;
ccb->cdb_length = 6;
/* For INQUIRY sets cam_flags and cdb[0] */
ccb->cam_flags = NO_DATA;
ccb->cdb[0] = INQUIRY; /* 0x12 SCSI Opcode for Inquiry Command */
ccb->cdb[1] = 0;
ccb->cdb[2] = 0;
ccb->cdb[3] = 0;
ccb->cdb[4] = 3200;
ccb->cdb[5] = 0;
The SCSI Command is successful . How do i capture the output of INQUIRY command so that i can get
Vendor ID / Product ID ??
I have declared the Execute I/O SCSI buffer as follows
typedef struct {
long ccb_address; /* Address of this CCB */
short ccb_length; /* CAM Control Block Length */
char cam_opcode; /* CAM Operation Code */
char status; /* CAM Status */
long connect_id; /* Connect ID - no fields supported */
long cam_flags; /* CAM Flags */
long pd_pointer; /* Peripheral driver pointer */
long next_ccb_ptr; /* Next CCB Pointer */
long req_map_info; /* Request mapping information */
long call_on_comp; /* Callback on completion */
long data_buf_ptr; /* Data Buffer Pointer */
long data_xfer_length; /* Data transfer length */
long sense_buf_ptr; /* Sense information buffer pointer */
char sense_buf_length; /* Sense information buffer length */
char cdb_length; /* Command Descriptor Block (CDB) **
** length */
short num_sg_entries; /* Number of scatter/gather entries */
long vendor_unique; /* Vendor Unique field */
char scsi_status; /* SCSI status */
char auto_resid; /* Auto sense residual length */
short reserved; /* Reserved */
long resid_length; /* Residual length */
char cdb[12]; /* Command Descriptor Block (CDB) */
long time_out; /* Time-out value */
long msg_buf_ptr; /* Message buffer pointer */
short msg_buf_length; /* Message buffer length */
short vu_flags; /* Vendor-unique flags */
char tag_queue_act; /* Tagged Queue action */
char tag_id; /* Tag ID (target only) */
char init_id; /* Initiator ID (target only) */
char reserved2; /* Reserved */
} Exec_IO_CCB;
This structure will never capture SCSI Output ?
I have declared the Inquiry Structure as follows . But I am not sure how Inquire command will
populate Inquiry_Data structure data ??
typedef struct {
short data_valid; /* Flag that indicates whether or not the */
/* structure has been filled in with */
/* inquiry data from the device. */
byte periph_qual;
byte periph_dev_type;
byte rmb;
byte iso_version;
byte ecma_version;
byte ansi_version;
byte resp_data_format;
byte rel_adr;
byte sync;
byte linked;
byte cmd_que;
byte sft_rst;
char vendor_id[9];
char prod_id[17];
char prod_rev[5];
char reserved;
} Inquiry_Data;
The first thing that you have assigned a short to cdb[4], but cdb[4] is a byte. The assignment probably put a 0 there since the compiler would truncate. Since bytes 3 and 4 are the allocation length you have told the target not to send anything. Maybe you ment to assign 32 to cdb[4]; but since your Inquiry_Data structure is 44 bytes you probably want to assign 44 to cdb[4].

Where to find the general definition of i2c "master_xfer" function?

struct i2c_algorithm has function pointer template for master_xfer for i2c bus implementation. Where can I find the default function routine of master_xfer in linux kernel source.?
Please someone guide me..
What master_xfer is set to depends on your platform and bus. Look under drivers/i2c/busses/ to find where this function pointer is set. Note that it could be set to NULL.
An example of where it is set is in drivers/i2c/busses/i2c-pxa.c:
static const struct i2c_algorithm i2c_pxa_algorithm = {
.master_xfer = i2c_pxa_xfer,
.functionality = i2c_pxa_functionality,
};
Also look at include/linux/i2c.h:
struct i2c_algorithm {
/* If an adapter algorithm can't do I2C-level access, set master_xfer
to NULL. If an adapter algorithm can do SMBus access, set
smbus_xfer. If set to NULL, the SMBus protocol is simulated
using common I2C messages */
/* master_xfer should return the number of messages successfully
processed, or a negative value on error */
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num);
int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data);
/* To determine what the adapter supports */
u32 (*functionality) (struct i2c_adapter *);
};
:
* An i2c_msg is the low level representation of one segment of an I2C
* transaction. It is visible to drivers in the #i2c_transfer() procedure,
* to userspace from i2c-dev, and to I2C adapter drivers through the
* #i2c_adapter.#master_xfer() method.
*
There is i2c-gpio.c file in /driver/i2c/busses/. In that we are filling master_xfer function with bit_xfer. It does bit banging implementation.

Netfiler hook not getting called

I am writing a kernel module which registers a hook with netfilter. The handler is not being called if I ssh/telnet into the machine where the module is loaded.
struct nf_hook_ops my_hook_ops;
my_hook_ops.hook = hook_handler;
my_hook_ops.pf = PF_INET;
my_hook_ops.hooknum = NF_INET_PRE_ROUTING;
my_hook_ops.priority = NF_IP_PRI_FIRST;
nf_register_hook(&my_hook_ops);
The handler function:
unsigned int hook_handler(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
if(!skb)
return NF_ACCEPT;
struct iphdr* ip_header;
struct tcphdr* tcp_header;
union ip_address ipaddr;
printk(KERN_INFO "Entered handler\n");
if(skb->protocol == 8)
return NF_ACCEPT;
// Log the received packet
ip_header = ip_hdr(skb);
tcp_header = tcp_hdr(skb);
ipaddr.saddr = ip_header->saddr;
printk(KERN_INFO "Received packet:\nIP Address: %u.%u.%u.%u\nProtocol: %d\nSource port: %d\nDestination port: %d\n",
ipaddr.a[0],ipaddr.a[1],ipaddr.a[2],ipaddr.a[3],
skb->protocol,
tcp_header->source,
tcp_header->dest);
return NF_ACCEPT;
}
The hook is being called for protocol 8 (Exterior Gateway Protocol). The second printk never gets printed. Am I missing anything?
The protocol used here is different from the IP protocol number as assigned by IANA, for which 8 is for EGP and EGP has been outdated.
The protocol field for sk_buff is defined in , for which 8 is for ETH_P_IP. As your data is allways IP traffic,the first conditional check is always true. So the second part of code never get executed.
A couple of thoughts:
a hook handler takes a (struct skbuff **), not a (struct skbuff *)
following on from the above, skb->protocol doesn't exist. You want either (*skb)->protocol or you want the following idiom:
struct sk_buff *sock_buf = *skb;
if(sock_buff->protocol)
If the packet is an EGP packet, you should not be expecting output from the second printk, because you return before it.
You need to study how sk_buff works, the protocol field initialized by the function `eth_type_trans' which takes on ETH_P_* values. All ETH_P_* values are defined in if_ether. Here are some of these values.
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
You clearly see that 0x08 is defined for Internet Protocol packet. And your code clearly return in case of 8 (which is IP packet)
if(skb->protocol == 8)
return NF_ACCEPT;
Your ssh/telnet clearly IP packet(s) and rejected by above code. Please use proper protocol defined values defined in if_ethr

Resources