BPF write fails with 1514 bytes - c

I'm unable to write 1514 bytes (including the L2 information) via write to /dev/bpf. I can write smaller packets (meaning I think the basic setup is correct), but I see "Message too long" with the full-length packets. This is on Solaris 11.2.
It's as though the write is treating this as the write of an IP packet.
Per the specs, there 1500 bytes for the IP portion, 14 for the L2 headers (18 if tagging), and 4 bytes for the checksum.
I've set the feature that I thought would prevent the OS from adding its own layer 2 information (yes, I also find it odd that a 1 disables it; pseudo code below):
int hdr_complete = 1;
ioctl(bpf, BIOCSHDRCMPLT, &hdr_complete);
The packets are never larger than 1514 bytes (they're captured via a port span and start with the source and destination MAC addresses; I'm effectively replaying them).
I'm sure I'm missing something basic here, but I'm hitting a dead end. Any pointers would be much appreciated!
Partial Answer: This link was very helpful.
Update 3/20/2017
Code works on Mac OS X, but on Solaris results in repeated "Interrupted system call" (EINTR). I'm starting to read scary things about having to implement signal handling, which I'd rather not do...
Sample code on GitHub based on various code I've found via Google. On most systems you have to run this with root privileges unless you've granted "net_rawaccess" to the user.
Still trying to figure out the EINTR issue. Output from truss:
27158/1: 0.0122 0.0000 write(3, 0x08081DD0, 1514) Err#4 EINTR
27158/1: \0 >E1C09B92 4159E01C694\b\0 E\005DC82E1 #\0 #06F8 xC0A81C\fC0A8
27158/1: 1C eC8EF14 Q nB0BC 4 V #FBDE8010FFFF8313\0\00101\b\n ^F3 W # C E
27158/1: d SDD G14EDEB ~ t sCFADC6 qE3C3B7 ,D9D51D VB0DFB0\b96C4B8EC1C90
27158/1: 12F9D7 &E6C2A4 Z 6 t\bFCE5EBBF9C1798 r 4EF "139F +A9 cE3957F tA7
27158/1: x KCD _0E qB9 DE5C1 #CAACFF gC398D9F787FB\n & &B389\n H\t ~EF81
27158/1: C9BCE0D7 .9A1B13 [ [DE\b [ ECBF31EC3 z19CDA0 #81 ) JC9 2C8B9B491
27158/1: u94 iA3 .84B78AE09592 ;DA ] .F8 A811EE H Q o q9B 8A4 cF1 XF5 g
27158/1: EC ^\n1BE2C1A5C2 V 7FD 094 + (B5D3 :A31B8B128D ' J 18A <897FA3 u
EDIT 7 April 2017
The EINTR problem was the result of a bug in the sample code that I placed on GitHub. The code was not associating the bpf device with the actual interface and Solaris was throwing the EINTR as a result.
Now I'm back to the "message too long" problem that I still haven't resolved.

Related

What do the values in 'alsa --dump-hw-params' represent?

I am having problems configuring ALSA on my RHEL 7.5 machine.
Part of my solution is to attempt to change settings in /etc/asound.conf. I have tried numerous permutations but I continue to hear "jitter" in my sounds (.raw files).
I am using the 'aplay --dump-hw-params to get the params for my sound HW.
Using this command:
aplay --dump-hw-params Front_Center.wav
These are the results I get:
Playing WAVE 'Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
HW Params of device "default":
--------------------
ACCESS: MMAP_INTERLEAVED MMAP_NONINTERLEAVED MMAP_COMPLEX RW_INTERLEAVED RW_NONINTERLEAVED
FORMAT: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE FLOAT64_LE FLOAT64_BE MU_LAW A_LAW IMA_ADPCM S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE U18_3BE
SUBFORMAT: STD
SAMPLE_BITS: [4 64]
FRAME_BITS: [4 640000]
CHANNELS: [1 10000]
RATE: [4000 4294967295)
PERIOD_TIME: (11609 11610)
PERIOD_SIZE: (46 49864571)
PERIOD_BYTES: (23 4294967295)
PERIODS: (0 17344165)
BUFFER_TIME: [1 4294967295]
BUFFER_SIZE: [92 797831566]
BUFFER_BYTES: [46 4294967295]
TICK_TIME: ALL
--------------------
I'd like to know what the values within parens and braces mean in general.
Are they ranges?
What is the difference between the use of parens vs. braces?
Thanks,
Ian
Minimum and maximum values as supported by the specific hardware device you are using.

Difference between constants defined in Go's syscall and C's stat.h [duplicate]

Update: based on the comment and response so far, I guess I should make it explicit that I understand 0700 is the octal representation of the decimal number 448. My concern here is that when an octal mode parameter or when a decimal number is recast as octal and passed to the os.FileMode method the resulting permissions on the file created using WriteFile don't seem to line up in a way that makes sense.
I worked as hard as I could to reduce the size of the question to its essence, maybe I need to go thru another round of that
Update2: after re-re-reading, I think I can more succinctly state my issue. Calling os.FileMode(700) should be the same as calling it with the binary value 1-010-111-100. With those 9 least significant bits there should be permissions of:
--w-rwxr-- or 274 in octal (and translates back to
Instead, that FileMode results in WriteFile creating the file with:
--w-r-xr-- which is 254 in octal.
When using an internal utility written in go, there was a file creation permission bug caused by using decimal 700 instead of octal 0700 when creating the file with ioutil.WriteFile(). That is:
ioutil.WriteFile("decimal.txt", "filecontents", 700) <- wrong!
ioutil.WriteFile("octal.txt", "filecontents", 0700) <- correct!
When using the decimal number (ie. no leading zero to identify it as an octal number to go_lang) the file that should have had permissions
0700 -> '-rwx------' had 0254 -> '--w-r-xr--'
After it was fixed, I noticed that when I converted 700 decimal to octal, I got “1274” instead of the experimental result of "0254".
When I converted 700 decimal to binary, I got: 1-010-111-100 (I added dashes where the rwx’s are separated). This looks like a permission of "0274" except for that leading bit being set.
I went looking at the go docs for FileMode and saw that under the covers FileMode is a uint32. The nine smallest bits map onto the standard unix file perm structure. The top 12 bits indicate special file features. I think that one leading bit in the tenth position is in unused territory.
I was still confused, so I tried:
package main
import (
"io/ioutil"
"fmt"
"os"
)
func main() {
content := []byte("temporary file's content")
modes := map[string]os.FileMode{
"700": os.FileMode(700),
"0700": os.FileMode(0700),
"1274": os.FileMode(1274),
"01274": os.FileMode(01274)}
for name, mode := range modes {
if err := ioutil.WriteFile(name, content, mode); err != nil {
fmt.Println("error creating ", name, " as ", mode)
}
if fi, err := os.Lstat(name); err == nil {
mode := fi.Mode()
fmt.Println("file\t", name, "\thas ", mode.String())
}
}
}
And now I'm even more confused. The results I got are:
file 700 has --w-r-xr--
file 0700 has -rwx------
file 1274 has --wxr-x---
file 01274 has --w-r-xr--
and was confirmed by looking at the filesystem:
--w-r-xr-- 1 rfagen staff 24 Jan 5 17:43 700
-rwx------ 1 rfagen staff 24 Jan 5 17:43 0700
--wxr-x--- 1 rfagen staff 24 Jan 5 17:43 1274
--w-r-xr-- 1 rfagen staff 24 Jan 5 17:43 01274
The first one is the broken situation that triggered the original bug in the internal application.
The second one is the corrected code working as expected.
The third one is bizarre, as 1274 decimal seems to translate into 0350
The fourth one kind of makes a twisted sort of sense, given that dec(700)->oct(1274) and explicitly asking for 01274 gives the same puzzling 0254 as the first case.
I have a vague suspicion that the extra part of the number larger than 2^9 is somehow messing it up but I can't figure it out, even after looking at the source for FileMode. As far as I can tell, it only ever looks at the 12 MSB and 9 LSB.
os.FileMode only knows about integers, it doesn't care whether the literal representation is octal or not.
The fact that 0700 is interpreted in base 8 comes from the language spec itself:
An integer literal is a sequence of digits representing an integer
constant. An optional prefix sets a non-decimal base: 0 for octal, 0x
or 0X for hexadecimal. In hexadecimal literals, letters a-f and A-F
represent values 10 through 15.
This is a fairly standard way of representing literal octal numbers in programming languages.
So your file mode was changed from the requested 0274 to the actual on-disk 0254. I'll bet that your umask is 0022. Sounds to me like everything is working fine.

Prolog , endless loop

I did t he following code to go through all student Ids starting from 476 and ending at 520.
schedule_errors(A,B,C):-
Errors is 0,
check_Courses(476,A,B,C,Errors).
check_Courses(X,A,B,C,Errors):-
. .
. .
. .
Y is X+1,
check_Courses(Y,A,B,C,Er).
The problem is the programm keeps running indefinetly ignoring my exit loop predicate
check_Courses(520,A,B,C,Er):-
write('Check complete').
I can't understand what i am doing wrong. i Tried a similar easier version (just counting to 10) and it works fine
loop(10):-
write('cd finished').
loop(X):-
write(X), nl,
Y is X+1,
loop(Y).
What am i missing?
One important observation is that loop/1 does not terminate either. You can see this for example as follows:
?- loop(1), false.
1
2
3
...
8
9
cd finished10
11
12
13
14
...
49
50
51
...
32394
32395
...
Note that the textual order in which you state your clauses in Prolog matters.
If you exchange the two clauses of loop/1, then you do not get a single solution, only an endless stream of output:
?- loop(1).
...
42642
42643
...
So, in check_courses/5, if you put a more specific case after a case that subsumes it, then the textually first clause will always be tried first.
Put simple cases before more complex cases!

out of order write a file python

I have multiple segments saved in an input file. The format is;
Use case 1:
host port start_byte end_byte
127.0.0.1 12345 0 2048
127.0.0.1 12346 0 1024
127.0.0.1 12347 1024 2048
Use case 2:
host port start_byte end_byte
127.0.0.1 12345 0 2048
127.0.0.1 12346 1024 2048
127.0.0.1 12347 0 1024
Here, the first line is for the reference to understand what each line has.
The host is the localhost but ports are different.
Here we have 3 ports. Port #12345 has entire file (say abc.txt). Port #12347 has
the second segment whereas the port #12346 has the first segment.
Now, I want to read file from the end of file towards the start of file(from line 3 to 1).
The code to download each segment and write to a new file is given below.
def downloadSegment(threadName, fileNameTemp, server_addr, server_port, segment_beginaddr, segment_endaddr, fileName, maxSegmentSize,ip_address,peer_server_port, relevant_path):
downloadSegmentStr = "download," + fileName + ","+segment_beginaddr+"," + segment_endaddr
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((server_addr, int(server_port)))
socket1.send(downloadSegmentStr)
lock.acquire()
with open(fileNameTemp, 'ab') as file_to_write:
file_to_write.seek(int(segment_beginaddr),0)
while True:
data = socket1.recv(maxSegmentSize)
#print data
if not data:
break
#print data
file_to_write.write(data)
file_to_write.close()
lock.release();
socket1.close()
When I write the segment in increasing order (Use case 1), then, it works perfectly. But, when I try using the out of order like explained in above Use case 2, it doesn't work.
Any help is appreciated. Thanks.
You missed these parts of the Python Documentation:
open(name[, mode[, buffering]])
… 'a' for appending (which on some Unix systems means that all
writes append to the end of the file regardless of the current seek
position).
file.seek(offset[, whence])
… Note that if the file is opened for appending (mode 'a' or 'a+'),
any seek() operations will be undone at the next write. If the file is
only opened for writing in append mode (mode 'a'), this method is
essentially a no-op…
Thus, mode 'a' is unsuitable for the task. Sadly, stdio's fopen() offers no mode without a that creates a file if it doesn't exist and doesn't truncate it if it exists. So I'd use os.open() like in:
with os.fdopen(os.open(fileNameTemp, os.O_CREAT|os.O_WRONLY), 'wb') as file_to_write:

linux driver for an i2c device -- two byte read

I'm trying to write a Linux driver for an I2C device that seems to be slightly different from a typical device. Specifically, I need to read two bytes in a row without sending a stop bit in between, like so:
[S] [Slave Addr | 0] [A] [Reg Addr 1] [A] [Sr] [Slave Addr | 1] [Data Byte 1] [NA]
[Sr][Slave Addr | 0] [A] [Reg Addr 2] [A] [Sr] [Slave Addr | 1] [Data Byte 2] [NA] [P]
I've looked at a few ways of doing this, including i2c_transfer(), i2c_master_send() and i2c_master_recv(), but I'm not sure if they will support these. Is there any way of doing this directly with these functions that isn't horribly painful? The documentation that I've found so far hasn't been entirely clear on the matter.
EDIT#1: adding symbols key to make it readable. Courtesy to http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/i2c/i2c-protocol
Key to symbols
==============
S (1 bit) : Start bit
P (1 bit) : Stop bit
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
A, NA (1 bit) : Accept and reverse accept bit.
Addr (7 bits): I2C 7 bit address. Note that this can be expanded as usual to
get a 10 bit I2C address.
Comm (8 bits): Command byte, a data byte which often selects a register on
the device.
Data (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh
for 16 bit data.
Count (8 bits): A data byte containing the length of a block operation.
[..]: Data sent by I2C device, as opposed to data sent by the host adapter.
no stop bit is send between bytes in the same read/write operation. i2c_master_recv is probably what you need.

Resources