I have a custom, DOS-like OS built in NASM completely (no C code). It is very modest (it does have a FAT file system, few apps, is in real mode, etc.) I want to write a command that will list all the network devices (network cards) that are currently connected.
My assumptions go like this: I will need to write a driver for the network card (I'd put it manually inside kernel for simplicity, so dynamic loading would NOT exist), but it would be enough for that driver to just provide the name of the card, the network card wouldn't actually need to work. How do I tell the OS to connect that function to precisely that one network card? This is what I'm in the blue about, I have no idea how the OS usually matches a piece of hardware to code (its driver(s)).
Since it appears from your comments that you have Dosbox supporting an NE2000 card then the code below should detect the presence of an NE2000 card (A port base of 0x300 is assumed). The code is a DOS COM program I wrote and should be compilable with a command like nasm ne2kchk.asm -fbin -o ne2kchk.com
NS_DATAPORT EQU 0x10 ; NatSemi-defined port window offset.
NE_DATAPORT EQU 0x10 ; NatSemi-defined port window offset.
NS_RESET EQU 0x1f ; Issue a read to reset, a write to clear.
NE1SM_START_PG EQU 0x20 ; First page of TX buffer
NE1SM_STOP_PG EQU 0x40 ; Last page +1 of RX ring
NESM_START_PG EQU 0x40 ; First page of TX buffer
NESM_STOP_PG EQU 0x80 ; Last page +1 of RX ring
E8390_CMD EQU 0x00 ; The command register (for all pages)
E8390_STOP EQU 0x01 ; Stop and reset the chip
E8390_START EQU 0x02 ; Start the chip, clear reset
E8390_RREAD EQU 0x08 ; Remote read
E8390_NODMA EQU 0x20 ; Remote DMA
E8390_PAGE0 EQU 0x00 ; Select page chip registers
E8390_PAGE1 EQU 0x40 ; using the two high-order bits
E8390_PAGE2 EQU 0x80
E8390_PAGE3 EQU 0xC0 ; Page 3 is invalid on the real 8390.
E8390_RXOFF EQU 0x20 ; EN0_RXCR: Accept no packets
E8390_TXOFF EQU 0x02 ; EN0_TXCR: Transmitter off
; Page 0 register offsets.
EN0_CLDALO EQU 0x01 ; Low byte of current local dma addr RD
EN0_STARTPG EQU 0x01 ; Starting page of ring bfr WR
EN0_CLDAHI EQU 0x02 ; High byte of current local dma addr RD
EN0_STOPPG EQU 0x02 ; Ending page +1 of ring bfr WR
EN0_BOUNDARY EQU 0x03 ; Boundary page of ring bfr RD WR
EN0_TSR EQU 0x04 ; Transmit status reg RD
EN0_TPSR EQU 0x04 ; Transmit starting page WR
EN0_NCR EQU 0x05 ; Number of collision reg RD
EN0_TCNTLO EQU 0x05 ; Low byte of tx byte count WR
EN0_FIFO EQU 0x06 ; FIFO RD
EN0_TCNTHI EQU 0x06 ; High byte of tx byte count WR
EN0_ISR EQU 0x07 ; Interrupt status reg RD WR
EN0_CRDALO EQU 0x08 ; low byte of current remote dma address RD
EN0_RSARLO EQU 0x08 ; Remote start address reg 0
EN0_CRDAHI EQU 0x09 ; high byte, current remote dma address RD
EN0_RSARHI EQU 0x09 ; Remote start address reg 1
EN0_RCNTLO EQU 0x0a ; Remote byte count reg WR
EN0_RCNTHI EQU 0x0b ; Remote byte count reg WR
EN0_RSR EQU 0x0c ; rx status reg RD
EN0_RXCR EQU 0x0c ; RX configuration reg WR
EN0_TXCR EQU 0x0d ; TX configuration reg WR
EN0_COUNTER0 EQU 0x0d ; Rcv alignment error counter RD
EN0_DCFG EQU 0x0e ; Data configuration reg WR
EN0_COUNTER1 EQU 0x0e ; Rcv CRC error counter RD
EN0_IMR EQU 0x0f ; Interrupt mask reg WR
EN0_COUNTER2 EQU 0x0f ; Rcv missed frame error counter RD
PORT_BASE EQU 0x300 ; Default base port
[BITS 16]
org 0x100
section .text
start:
push cs
pop ds
; Probe for NE2000 card
; Try non destructive test first
mov dx, PORT_BASE+E8390_CMD
in al, dx
cmp al, 0xff
jz .s_notfound
; Attempt potentially destuctive tests
mov al, E8390_NODMA | E8390_PAGE1 | E8390_STOP
mov dx, PORT_BASE+E8390_CMD
out dx, al ; Receive alignment error counter
mov dx, PORT_BASE+EN0_COUNTER0
in al, dx
mov cl, al ; Save to REGD (CL)
mov al, 0xff
out dx, al
mov al, E8390_NODMA | E8390_PAGE0
mov dx, PORT_BASE+E8390_CMD
out dx, al
mov dx, PORT_BASE+EN0_COUNTER0
in al, dx ; Clear the counter by reading.
test al, al
jz .s_found ; If al is clear then card was found
; Card not found
.s_notfound:
xchg al, cl ; Temporarily save al to avoid clobber
out dx, al
mov ah, 0x09
mov dx, notfound_str
int 0x21
xchg al, cl ; Restore al. al = error value to return
jmp .s_exit
; Card found
.s_found:
mov ah, 0x09
mov dx, found_str
int 0x21
xor al, al ; Clear the error code
; exit with al = errcode
.s_exit:
mov ah, 0x4C
int 0x21
notfound_str db "NE2000 not found", 0x0a, 0x0d, "$"
found_str db "NE2000 found", 0x0a, 0x0d, "$"
The code above is an adaptation of "C" code that I found in the Debian nictool code available here . It can be found in the file ne2k-diags.c. It seems more information (datasheets) are available for the rtl8019 which is a clone of the NE2000. The 8390NIC that is at the heart of these devices is documented here. The 8390 documentation discusses how to send and receive data. An excerpt of the "C" code that I based mine on was:
printf("Checking the ethercard at %#3x.\n", port_base);
{ int regd;
long ioaddr = port_base;
outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
regd = inb_p(ioaddr + 0x0d);
printk(" Receive alignment error counter (%#lx) is %2.2x\n",
ioaddr + 0x0d, regd);
outb_p(0xff, ioaddr + 0x0d);
outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
outb(regd, ioaddr + 0x0d); /* Restore the old values. */
printk(" Failed initial NE2000 probe, value %2.2x.\n",
inb(ioaddr + EN0_COUNTER0));
} else
printk(" Passed initial NE2000 probe, value %2.2x.\n",
inb(ioaddr + EN0_COUNTER0));
}
The code above is the initial probe but there is more "C" code in the same file that tries to detect some of the specific variants and query the card signature.
Related
So after a day of struggling I managed to get Debian 11 on a IMX7D, 5.4.129 kernel to recognize the MAX14830 and talk to it via the MAX310X driver. But when I try to send data with echo a > /dev/ttyMAX0 nothing happens. Well except the Tx count going up.
Looking at the SPI traffic this seems to be going correctly and the chip is sending the expected responses (Tx FIFO count returns three if three characters are being send) but nothing seems to happen to the buffer. The driver keeps interrogating the max but the FIFO stays at 3. Then the driver reaches a timeout I guess. Because it then sends 0x81,0x00 which clears the IRQen register, followed by 0x9B 0x40 which sets the baudrate register... which makes it all the more confusing.
So far I've gone through all the stty settings and used -ixon to disable XON/XOFF but that didn't make a difference.
Is there a way/place/file that holds the settings for the driver? Or am I forgetting something? RX doesn't seem to work either but not sure if the max isn't receiving it or just not informing the driver.
The relevant portion of the DTS
&ecspi3 {
max14830: max14830#3 {
compatible = "maxim,max14830";
spi-max-frequency = <15000000>;
reg = <0>; // SPI chip select number
clocks = <&clk16m0>;
clock-names = "osc";
interrupt-parent = <&gpio5>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
gpio-controller; // Marks the device node as a GPIO controller
#gpio-cells = <2>;
clk16m0: clk16m0 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <3686400>; // freq of external xtal
clock-accuracy = <100>;
};
};
};
And the comms during startup
OUT IN MEANING
0x9F 0xCE -> Write globalCmd = Enable Extend register map acces
0x05 0x00 -> 0x0F 0xB4 -> Clear SpclChrIntEn= RevID is B4
0x9F 0xCD -> Write globalCmd = Disable Extend register map access
0x8A 0x01 -> Write UART0 Mode2 = Set RST
0x8A 0x00 -> Write UART0 Mode2 = Clear RST
0x1C 0x00 -> 0x0F 0x01 -> Read UART0 DivLSB = Div0 set
0x89 0x80 -> Set UART0 MODE1 = ~RTS0 is three state
0xAA 0x01 -> Write UART1 Mode2 = Set RST
0xAA 0x00 -> Write UART1 Mode2 = Clear RST
0x3C 0x00 -> 0x0F 0x01 -> Read UART1 DivLSB = Div0 set
0xA9 0x80 -> Set UART1 MODE1 = ~RTS1 is three state
0xCA 0x01 -> Write UART2 Mode2 = Set RST
0xCA 0x00 -> Write UART2 Mode2 = Clear RST
0x5C 0x00 -> 0xF 0x01 -> Read UART2 DivLSB = Div0 set
0xC9 0x80 -> Set UART2 MODE1 = ~RTS2 is three state
0xEA 0x01 -> Write UART3 Mode2 = Set RST
0xEA 0x00 -> Write UART3 Mode2 = Clear RST
0x7C 0x00 -> 0x0F 0x01 -> Read UART3 DivLSB = Div0 set
0xE9 0x80 -> Set UART3 MODE1 = ~RTS3 is three state
0x9A 0x44 -> Write PLLConfig = Set PreDiv5 and PreDiv2
0x9E 0x14 -> Write ClockSource = 0001 0100 -> first 1 at dont care, second PLLen
0x81 0x00 -> Clear IRQen UART0
0x02 0x00 -> 0x0F 0x60 -> Read ISR UART0 = both fifo empty
0x1B 0x00 -> 0x0F 0x00 -> Read BRConfig UART0 -> all clear
0x9B 0x40 -> Write BRConfig UART0 -> FRACT2 Set
0xA1 0x00 -> Clear IRQen UART1
0x22 0x00 -> 0x0F 0x60 -> Read ISR UART1 = both fifo empty
0x3B 0x00 -> 0x0F 0x00 -> Read BRConfig UART1 -> all clear
0xBB 0x40 -> Write BRConfig UART1 -> FRACT2 Set
0xC1 0x00 -> Clear IRQen UART2
0x42 0x00 -> 0x0F 0x60 -> Read ISR UART2 = both fifo empty
0x58 0x00 -> 0x0F 0x00 -> Read BRConfig UART2 -> all clear
0xDB 0x40 -> Write BRConfig UART2 -> FRACT2 Set
0xE1 0x00 -> Clear IRQen UART3
0x62 0x00 -> 0x0F 0x60 -> Read ISR UART3 = both fifo empty
0x7B 0x00 -> 0x0F 0x00 -> Read BRConfig UART3 -> all clear
0xFB 0x40 -> Write BRConfig UART3 -> FRACT2 Set
ttyMAX0 setup according to stty
Result of stty -F /dev/ttyMAX0
-parenb -> don't generate parity
-parodd -> Even parity?
-cmspar -> No stick parity
cs8 -> character size 8 bits
hupcl -> don't send hangup signal
-cstopb -> use one bit per character
cread -> allow input to be received
clocal -> disable modem control signals
-crtscts -> dont enable rts/cts handschaking
-ignbr -> don't ignore break characters
-brkint -> breaks don't cause an interrupt signal
-ignpar -> don't ignore characters with parity errors
-parmrk -> don't mark parity errors
-inpck -> don't enable parity checking
-istrip -> don't clear high (8th) bit of input characters
-inlcr -> dont translate newline to carriage return
-igncr -> don't ignore carriage return
icrnl -> don't translate carriage return to newline
-ixon -> disable XON/XOFF flow control
-ixoff -> disable sending of start/stop characters
-iuclc -> don't translate uppercase to lowercase
-ixany -> Don't let any character restart output
-imaxbel -> don't beep and flush
-iutf8 -> don't assume characters are utf8 encoded
OUTPUT SETTINGS
opost -> post process output
-olcuc -> don't translate lower to upper
-ocrnl -> don't translate carriage return to newline
onlcr -> translate newline to carriage return newline
-onocr -> print carriage return in the first column
-onlret -> newline doesn't perform a carriage return
-ofill -> don't use fill characters instead of timing for delays
-ofdel -> don't use delete character for fill instead of null
nl0
cr0
tab0 -> horizontal tab delay style 0
bs0
vt0
ff0 -> form feed delay style
isig -> enable interrpt,
icanon -> enable special characters: erase, kill, werase, rprnt
iexten -> enable non-POSIX special characters
echo -> echo input characters
echoe -> echo erase characters as backspace-space-backspace
echok -> echo a newline after a kill character
-echonl
-noflsh -> don't disable flushing after interrupt & quit special
chars
-xcase
-tostop
-echoprt
echoctl -> echo control characters in hat notation ('^c')
echoke -> kill all line by obeying the echoprt and echoe settings
-flusho
-extproc
TX wasn't working because clock-names should have been xtal
RX wasn't working because i never opened the port but checked /proc/tty/driver/max310x for received data and the driver disables rx if a port isn't open.
Working node.
&ecspi3 {
/delete-node/spidev#0;
max14830: max14830#3 {
compatible = "maxim,max14830";
spi-max-frequency = <15000000>;
reg = <0>; // SPI chip select number
clocks = <&clk16m0>;
clock-names = "xtal"; /* because using external xtal */
interrupt-parent = <&gpio5>;
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
gpio-controller; /* Marks the device node as a GPIO controller */
#gpio-cells = <2>;
clk16m0: clk16m0 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <3686400>; /* external xtal frequency */
clock-accuracy = <100>;
};
};
};
```
I am developing a project where I have to read the holding registers data. I check everything using this http://www.freemodbus.com/ and it is working and get a proper response. While trying with the developed program I am not getting the proper response.
Software Response: 0x01 0x03 0x04 0x1a 0xa0 0x42 0x48 0xcd 0x9f
Arduino response: 0x01 0x04 0x83 0x43 0xff 0xff 0xff 0xff 0xff
note that in Arduino response there is no 0x03 after 0x01 I don't know why it is happening can anyone please help me with this.
please find attached Arduino code below.
static union
{
unsigned long a;
byte b[4];
float f;
}vr;
void readregister(unsigned int address)
{
byte rxbuf[]={0,0,0,0,0,0,0,0,0,0,0};
byte data[] = {0x01,0x03,0x00,0xab,0x00,0x02,0xb5,0xeb};
Serial3.flush();
for(int i=0;i<8;i++)
{
Serial3.write(data[i]);
}
delay(250);
while(Serial3.available()>0)
{
for(int v=0; v<=10;v++)
{
rxbuf[v]=Serial3.read();
Serial.println(rxbuf[v],HEX);
}
}
Serial3.flush();
vr.b[3]=rxbuf[3];
vr.b[2]=rxbuf[2];
vr.b[1]=rxbuf[5];
vr.b[0]=rxbuf[4];
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial3.begin(9600,SERIAL_8E1);
}
void loop() {
// put your main code here, to run repeatedly:
readregister(99);
Serial.print("\n");
delay(3000);
}
Yes, I think you're getting an Error code 4 back from the device. See http://www.simplymodbus.ca/exceptions.htm
On this line, where you prep your request:
byte data[] = {0x01,0x03,0x00,0xab,0x00,0x02,0xb5,0xeb};
You're saying, device 1, function 3, 0x00 is space, then register address 0xAB. Not sure about the extra zero then, then length 2, and then CRC. So I vote that either the CRC is wrong, or the extra zero is wrong.
Also, note that modbus fails on ocassion for no reason, even when you do everything right, so retry after a few seconds and see what happens
I'm trying to send HEX values via XBee from a Arduino to digi's Xbee program XCTU. But i have some problems with some bytes that i cant send
The list of bytes i cant send:
0x11
0x13
0x7D
0x7E
0x81
0xEC
0xEE
If i use any other bytes i can see it in the XCTU console window and i get a response back to the Arduino
I have enabled API mode (AP=1) on both of the Xbee's. Im using the XBee lib linked from Arduino web site (https://www.arduino.cc/en/Reference/Libraries)
My code looks like this:
#define XBEE_RX_PIN 8
#define XBEE_TX_PIN 9
SoftwareSerial xbeeSerial(XBEE_RX_PIN, XBEE_TX_PIN);
void setup()
{
Serial.begin(9600);
xbeeSerial.begin(9600);
xbee.begin(xbeeSerial);
}
void loop()
{
Serial.println("Send next 255 msg:");
uint8_t testMsg[1] = { 0x0 };
for (uint8_t i = 0; i <= 0xFF; i++)
{
test2[0] = i;
Tx16Request testTx = Tx16Request(0xFFFF, testMsg, sizeof(testMsg));
xbee.send(testTx);
Serial.print("Message send: ");
Serial.println(test2[0], HEX);
if (xbee.readPacket(5000)) {
Serial.println("SUCCESS");
}
else if (xbee.getResponse().isError()) {
Serial.println("isError");
}
else {
Serial.println("No Response");
}
}
Serial.println("");
delay(3000);
}
With AP=1, you can't send some special bytes like:
0x7E (start of frame)
0x11/0x13 (XOn XOff)
...
As mentioned in the XBee documentation (XBee®XBee-PRO® ZB RF Modules manual 90000976_W.pdf, starting page 112), you should use AP=2 mode which allows you to transmit these special bytes by escaping them:
Escape characters.
When sending or receiving a UART data frame, specific data values must be
escaped (flagged) so they do not interfere with the data frame sequencing.
To escape an interfering data byte, insert 0x7D and follow it with the byte to be escaped XOR’d with 0x20.
Note that, if not escaped, 0x11 and 0x13 is sent as is.
Data bytes that need to be escaped:
- 0x7E – Frame Delimiter
- 0x7D – Escape
- 0x11 – XON
- 0x13 – XOFF
Example - Raw UART Data Frame (before escaping interfering bytes):
- 0x7E 0x00 0x02 0x23 0x11 0xCB
0x11 needs to be escaped which results in the following frame:
- 0x7E 0x00 0x02 0x23 0x7D 0x31 0xCB
Note In the above example, the length of the raw data (excluding the checksum) is 0x0002 and the checksum of the non-escaped data (excluding frame delimiter and length) is calculated as:
0xFF - (0x23 + 0x11) = (0xFF - 0x34) = 0xCB.
Hope this helps
I'm trying to simulate the following program with MPLAB X simulator, but the ADC seems not working. I have attached a stimulus file with '0303' values to the ADRESL register but I have no read and in the simulator console i got a warning "ADC-W101: Selected channel is configured as digital IO. The channel selected:0.". Moreover once set, the ADCON0 GO bit doesn't clear, even if the ADIF is triggered. The pic is a 16f88.
Is it a problem of the MPLAB X simulator? I've checked the limitations of MPLABX sim with the 16f88 but there is nothing about the ADC.
processor 16f88
include <P16F88.INC>
errorlevel 0, -302 ; suppress messages about bank selection
__CONFIG _CONFIG1, _WDT_OFF & _FOSC_INTOSCIO & _MCLR_ON & _LVP_OFF
udata
LIGHT_SENS res 2
TEMP_W res 1
TEMP_STATUS res 1
TEMP_PCLATH res 1
FLAGS res 1
TIME1 equ h'00000'
ADC equ h'00001'
reset code 0x00
pagesel main
goto main
isr code 0x04
_isr_entry:
movwf TEMP_W
swapf STATUS, W
clrf STATUS
movwf TEMP_STATUS
movf PCLATH, W
movwf TEMP_PCLATH
clrf PCLATH
_isr_test_tmr0:
banksel INTCON
btfss INTCON, TMR0IF
goto _isr_test_adc
_tmr0_isr:
_tmr0_isr_entry:
banksel TMR0
movlw d'100'
movwf TMR0
bsf FLAGS, TIME1
_tmr0_isr_exit:
banksel INTCON
bcf INTCON, TMR0IF
_isr_test_adc:
banksel PIR1
btfss PIR1, ADIF
goto _isr_exit
_adc_isr:
_adc_isr_entry:
banksel FLAGS
bsf FLAGS, ADC
_adc_isr_exit:
banksel PIR1
bcf PIR1, ADIF
_isr_exit:
movf TEMP_PCLATH, W
movwf PCLATH
swapf TEMP_STATUS, W
movwf STATUS
swapf TEMP_W, F
swapf TEMP_W, W
retfie
;===============================================================================
main code
main
_setup_oscillator:
banksel OSCCON
movlw b'01100000' ; 4 MHz Internal Oscillator Clock Speed
movwf OSCCON
clrf OSCTUNE ; Center frequency
;===============================================================================
_setup_pin:
banksel PORTA
clrf PORTA ; clears the latch on PORTA before configuring it
banksel PORTB
clrf PORTB ; clears the latch on PORTB before configuring it
_setup_tmr0:
banksel TMR0
movlw d'100'
movwf TMR0
banksel OPTION_REG
movlw b'11010101' ; Prescaler is assigned to Timer0, rate 1:256, Timer mode
movwf OPTION_REG
bsf INTCON, TMR0IE ; enables Timer0 Overflow Interrupt
_setup_adcs:
banksel TRISA ; set PORTA pin direction
movlw h'01' ; RA0 is analog input
movwf TRISA
banksel ANSEL ; select analog pins
movlw h'01' ; AN0 is analog I/O
movwf ANSEL
banksel ADCON0 ; A/D channel selection
movlw b'10000000' ; channel AN0 selected
movwf ADCON0
banksel ADCON1 ; voltage reference, result justification, A/D clock
movlw b'10000000' ; right just, Vdd/Vss ref
movwf ADCON1
banksel ADCON0
bsf ADCON0, ADON
banksel PIE1
bsf PIE1, ADIE
banksel PIR1 ; enables A/DC interrupt
bcf PIR1, ADIF
banksel INTCON
bsf INTCON, GIE ; enables global interrupt
bsf INTCON, PEIE ; enables peripheral interrupt
_setup_application:
clrf FLAGS
_main_loop:
call CheckAdc
_main_loop_exit:
clrf FLAGS
goto _main_loop
;===============================================================================
CheckAdc
_CheckAdc_entry:
banksel FLAGS
btfss FLAGS, ADC ; tests if ADC is ready
goto _CheckAdc_restart
banksel ADRESL
movf ADRESL, W
banksel LIGHT_SENS
movwf LIGHT_SENS
banksel ADRESH
movf ADRESH, W
banksel LIGHT_SENS
movwf LIGHT_SENS+1
_CheckAdc_restart:
banksel FLAGS
btfss FLAGS, TIME1 ; tests if 1ms timer run out
goto _CheckAdc_exit
banksel ADCON0
btfss ADCON0, GO
bsf ADCON0, GO
_CheckAdc_exit:
return
end ; End Of Program
sniffex.c is a program that is based on libpcap , to sniff and display some packet information. How do i modify it so as to print the values of TCP flags - urg , ack , psh , rst , syn and fin ? please help..
If you check this code where sniff_tcp is used, make sure to print out
th_flags member of this structure which contians flags you need.
/* TCP header */
struct sniff_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_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
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
Generally you will have something like this (a bit ugly, you can do it better):
//this is already there in the code:
printf(" Src port: %d\n", ntohs(tcp->th_sport));
printf(" Dst port: %d\n", ntohs(tcp->th_dport))
//you add:
if (tcp->th_flags & TH_ECE){
printf(" Flag: TH_ECE");
}
if (tcp->th_flags & TH_RST){
printf(" Flag: TH_RST");
}