Rust OSError 22, Invalid argument when writing valid data to socket - sockets

I'm struggling to understand why I'm getting this error from a part of my program which sends ICMP echo requests on the network. The starnge thing about this is that I can get it to work by letting the socket handle the IP header, but when I set the IP_HDRINCL option and give it a valid IP header, it returns EINVAL error:
initialize
using interface en0 with ip 192.168.1.126 and mac a4:83:e7:43:40:81.
Input start ip/scan range: 192.168.1.1
[45, 0, 0, 1c, 20, 1, 40, 0, 40, 1, 97, 10, c0, a8, 1, 7e, c0, a8, 1, 1, 8, 0, 22, 2a, 97, 3e, 3e, 97]
[69, 0, 0, 28, 32, 1, 64, 0, 64, 1, 151, 16, 192, 168, 1, 126, 192, 168, 1, 1, 8, 0, 34, 42, 151, 62, 62, 151]
Err(Os { code: 22, kind: InvalidInput, message: "Invalid argument" })
To help visualise what's going on, I've put dumps of the data being sent in there when it sends it. the first dump is the data in hex format and the second is just the same but in decimal format.
Here is the code which opens the socket and creates/sends/receives packets:
( Apologies for the probably overwhelming amount of code, just though I should make sure I provide enough info:) )
let response = net_tools::interface::Interface::detect();
if response.is_err() {
panic! {response};
}
let active_interface = response.unwrap();
println!(
"using interface {} with ip {} and mac {}.",
active_interface.get_name(),
active_interface.get_ip_as_struct(),
active_interface.get_mac()
);
let scan_targets = net_tools::TaregtAddresses::retrieve_from_user();
let sock = net_tools::socket_tools::Socket::new_v4().expect("Failed to open socket");
let mut i = 0;
for ipv4addr in scan_targets {
if i == 1 {
break;
}
let mut d = packet_crafter::Packet::new(
active_interface.clone(),
vec![Protocols::IP, Protocols::ICMP],
// vec![Protocols::ICMP],
);
d.ip_header.set_next_protocol(Protocols::ICMP);
d.ip_header.set_dst_ip(Some(ipv4addr.octets()));
// d.ip_header.set_tos(0b11000100);
d.finalize_headers(); // calculates checksums etc
let data = d.build();
println!("{:x?}", data);
println!("{:?}", data);
let response = sock.sendto(data.as_slice(), SocketAddrV4::new(ipv4addr, 21));
println!("{:?}", response);
i += 1;
}
println!("All data sent, receiving response:");
let mut a = [0u8; 56];
let received_data = sock.recv(&mut a);
println!("{:?}", received_data);
let v = a.to_vec();
println!("{:?}", v);
This is how I'm opening a socket, and sending data on it, notice that I call setsockopt and set IP_HDRINCL to 1 when opening it:
pub fn new_v4() -> crate::io::Result<Self> {
unsafe {
let fam = libc::AF_INET; // Set domain family to ipv4
if cfg!(target_os = "linux") {
match cvt(libc::socket(fam, libc::SOCK_RAW | SOCK_CLOEXEC, 1)) {
Ok(fd) => return Ok(Self(Fd::new(fd))),
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
Err(e) => return Err(e),
}
}
let _fd = cvt(libc::socket(fam, libc::SOCK_RAW, 1))?; // 1 = setting next protocol as ICMP
let _fd = Fd::new(_fd);
_fd.set_cloexec()?;
let socket = Self(_fd);
if cfg!(target_vendor = "apple") {
let payload = &1u32 as *const u32 as *const libc::c_void;
cvt(libc::setsockopt(
*socket.as_inner(),
libc::SOL_SOCKET,
SO_NOSIGPIPE,
payload,
size_of::<libc::c_int>() as libc::socklen_t,
))?;
}
let payload = &1u32 as *const u32 as *const libc::c_void;
cvt(libc::setsockopt(
*socket.as_inner(),
libc::IPPROTO_IP,
libc::IP_HDRINCL,
payload,
size_of::<libc::c_int>() as libc::socklen_t,
))?;
Ok(socket)
}
}
pub fn sendto(&self, buf: &[u8], addr: SocketAddrV4) -> crate::io::Result<usize> {
unsafe {
let (sa, l) = sock_addr_into_raw(addr);
let n = cvt({
libc::sendto(
*self.as_inner(),
buf.as_ptr() as *const libc::c_void,
cmp::min(buf.len(), super::max_len()),
MSG_NOSIGNAL,
&sa as *const _,
l,
)
})?;
Ok(n as usize)
}
}
This is the function to convert the type of the socketAddr:
pub fn sock_addr_into_raw(s: SocketAddrV4) -> (libc::sockaddr, libc::socklen_t) {
unsafe {
let mut storage = mem::MaybeUninit::<libc::sockaddr>::uninit();
let len = mem::size_of::<SocketAddrV4>();
copy_nonoverlapping(
&s as *const _ as *const libc::sockaddr as *const _ as *const u8,
&mut storage as *mut _ as *mut u8,
len,
);
(storage.assume_init(), len as _)
}
}
So back to my point, as you can see from the first segment of code, the IP header in the packet data that I dump is a valid IP header, followed by a valid ICMP header, as far as I'm aware, I have been changing things around to ensure it's valid so correct me if its not. But anyway, I know that all the other parameters being passed into sendto are valid because when I set the IP_HDRINCL socket option to 0 and only send ICMP data then it works...
initialize
using interface en0 with ip 192.168.1.126 and mac a4:83:e7:43:40:81.
Input start ip/scan range: 192.168.1.1
[8, 0, 8a, 92, 3f, 2e, 2e, 3f]
[8, 0, 138, 146, 63, 46, 46, 63]
Ok(8)
All data sent, receiving response:
Ok(28)
[69, 0, 8, 0, 224, 108, 0, 0, 254, 1, 88, 164, 192, 168, 1, 1, 192, 168, 1, 126, 0, 0, 146, 146, 63, 46, 46, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
I've even tried things such as sending an ethernet II header in the packet when IP_HDRINCL is 1, but that still just gives the same OSError. Does anyone know why sending the IP header myself breaks it??
(btw I'm running this on Mac OS Mojave 10.14.6)

Related

How to get beacons UUID, when scanning for BLE

I am using this library https://pub.dev/packages/flutter_reactive_ble for scanning the beacon. and for broadcasting a beacon I am using an android app called beacon simulator and it has got beacon UUID, majorID and minorID for each hosted beacon.
here the UUID is '0546b93b-f113-438d-8bab-b9e766dd'
but while scanning I am unable to look out for UUID instead I am getting this response in this structure.
DiscoveredDevice(id: 14:49:2F:BB:D5:97, name: , serviceData: {}, serviceUuids: [], manufacturerData: [76, 0, 2, 21, 5, 70, 185, 59, 241, 19, 67, 141, 139, 171, 185, 231, 102, 208, 17, 119, 0, 0, 0, 0, 191], rssi: -39)
Is there any way I can get the beacon's UUID in the format '0546b93b-f113-438d-8ba...'
Or any better way to uniquely identify a device? I know we can search for the device's Bluetooth address, but that just keeps on changing.
Thanks in advance.

Problems with ICMP socket socket2 crate

I've written an application to send and receive ICMP packets (a ping redo, so to speak).
I've tested this on different computers and found that the code only runs on my MacOS. Other linux machines (I tested on many different flavors of Linux) gave wrong results, and I don't even know where to debug anymore.
Expected output, this is what comes out of my MacOS
[2022-06-17T18:37:47Z INFO layer4_ip] Received 84 bytes from 142.250.69.206:0
[2022-06-17T18:37:47Z INFO layer4_ip] Received Ipv4Packet { version : 4, header_length : 5, dscp : 0, ecn : 0, total_length : 16384, identification : 0, flags : 0, fragment_offset : 0, ttl : 119, next_level_protocol : IpNextHeaderProtocol(1), checksum : 44214, source : 142.250.69.206, destination : 192.168.1.130, options : [], }
[2022-06-17T18:37:48Z INFO layer4_ip] Received 84 bytes from 142.250.69.206:0
[2022-06-17T18:37:48Z INFO layer4_ip] Received Ipv4Packet { version : 4, header_length : 5, dscp : 0, ecn : 0, total_length : 16384, identification : 0, flags : 0, fragment_offset : 0, ttl : 119, next_level_protocol : IpNextHeaderProtocol(1), checksum : 44214, source : 142.250.69.206, destination : 192.168.1.130, options : [], }
Linux output (wrong output):
[2022-06-17T18:32:54Z INFO ping_playground] Received 64 bytes from 142.250.69.206:0
[2022-06-17T18:32:54Z INFO ping_playground] Received Ipv4Packet { version : 0, header_length : 0, dscp : 0, ecn : 0, total_length : 65454, identification : 80, flags : 0, fragment_offset : 1, ttl : 0, next_level_protocol : IpNextHeaderProtocol(0), checksum : 0, source : 0.0.0.0, destination : 0.0.0.0, options : [], }
[2022-06-17T18:32:55Z INFO ping_playground] Received 64 bytes from 142.250.69.206:0
[2022-06-17T18:32:55Z INFO ping_playground] Received Ipv4Packet { version : 0, header_length : 0, dscp : 0, ecn : 0, total_length : 65454, identification : 80, flags : 0, fragment_offset : 1, ttl : 0, next_level_protocol : IpNextHeaderProtocol(0), checksum : 0, source : 0.0.0.0, destination : 0.0.0.0, options : [], }
Not only the number of bytes read is different, but the parsing is wrong.
Intercepting in wireshark shows that the packets that are received back are indeed the same on my MacOS and Linux machines.
Here's the minimal version that presents the problem:
use std::{
net::{IpAddr, Ipv4Addr, SocketAddr},
os::unix::prelude::{AsRawFd, FromRawFd},
sync::Arc,
time::Duration,
};
use env_logger::Env;
use log::info;
use pnet_packet::{
icmp::{self},
Packet,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
// SOURCE IP ADDRESS
// let localhost = Ipv4Addr::LOCALHOST;
let localhost = Ipv4Addr::UNSPECIFIED;
let socket_ip_address = SocketAddr::new(IpAddr::V4(localhost), 80);
let socket2_ip_address = socket_ip_address.into();
// CREATE ICMP SOCKET
let socket2_ipv4_socket = socket2::Socket::new(
socket2::Domain::IPV4,
socket2::Type::DGRAM,
Some(socket2::Protocol::ICMPV4),
)
.unwrap();
// BIND TO LOCAL ADDRESS
socket2_ipv4_socket
.bind(&socket2_ip_address)
.expect(&format!(
"Failed binding to Ipv4 address {:?}",
&socket_ip_address
));
// CREATE STD SOCKET FROM SOCKET2 SOCKET
let raw_ipv4_socket = socket2_ipv4_socket.as_raw_fd();
let std_ipv4_socket = unsafe { std::net::UdpSocket::from_raw_fd(raw_ipv4_socket) };
std_ipv4_socket.set_read_timeout(Some(Duration::from_millis(100)))?;
let socket_arc = Arc::new(std_ipv4_socket);
let dest = "142.250.69.206:0";
let mut buffer = [0; 1024];
let socket_clone = Arc::clone(&socket_arc);
std::thread::spawn(move || {
let packet_slice = &mut [0; 56];
let mut buf = vec![0; 8 + 56]; // 8 bytes of header, then payload
let mut packet = icmp::echo_request::MutableEchoRequestPacket::new(&mut buf[..]).unwrap();
packet.set_icmp_type(icmp::IcmpTypes::EchoRequest);
packet.set_identifier(1);
packet.set_sequence_number(1);
packet.set_payload(packet_slice);
// Calculate and set the checksum
let icmp_packet = icmp::IcmpPacket::new(packet.packet()).unwrap();
let checksum = icmp::checksum(&icmp_packet);
packet.set_checksum(checksum);
loop {
socket_clone.send_to(&mut packet.packet(), dest).unwrap();
std::thread::sleep(Duration::from_millis(1000));
}
});
loop {
if let Ok((bytes_read, from)) = socket_arc.recv_from(&mut buffer) {
info!("Received {} bytes from {:?}", bytes_read, from);
let ipv4_packet = pnet_packet::ipv4::Ipv4Packet::new(&buffer).unwrap();
let _icmp_packet = pnet_packet::icmp::IcmpPacket::new(ipv4_packet.payload()).unwrap();
let _udp_packet = pnet_packet::udp::UdpPacket::new(&ipv4_packet.payload()).unwrap();
info!("Received {:?}", ipv4_packet);
}
}
}
Here's the dependencies part of Cargo.toml:
[dependencies]
pnet_packet = "0.29"
log = "0.4"
env_logger = "0.9"
socket2 = "0.4"
First, I would like someone to confirm this behavior.
Second, I would like help in figuring out what's wrong.
Thank you
Dummy me.
To receive the IP header I had to use a RAW socket and not the DGRAM.
Changing the socket creation to:
let socket2_ipv4_socket = socket2::Socket::new(
socket2::Domain::IPV4,
socket2::Type::RAW,
Some(socket2::Protocol::ICMPV4),
)
.unwrap();
That comes with the caveat that you have to give the right capabilities to your binary. Something like this, for example:
cargo build && sudo sudo setcap cap_net_raw+ep target/debug/ping_playground && target/debug/ping_playground
Closing the question.

How can I split an array into specified lines when printing?

New to software development, I'm working through Big Nerd Ranch's book 'Swift Programming'. One of the challenges set by the book is to print an array within a dictionary that contains 15 zip codes and to have them split across three lines in groups of five. The formatting must exactly match how it appears in the book.
I have tried to solve the issue using the information taught in the book with assistance from the developer documentation.
No dice.
This is what I need to print:
Caterham has the following zip codes: [111, 111, 111, 111, 111,
222, 222, 222, 222, 222,
333, 333, 333, 333, 333]
However this is the closest I can get...
var areaCodes = ["Caterham": [111, 111, 111, 111, 111], "Coulsdon": [222, 222, 222, 222, 222], "Purley": [333, 333, 333, 333, 333]]
var caterhamCodes : [Int] = []
for (_, values) in areaCodes {
caterhamCodes += values
}
print("Caterham has the following codes: \(caterhamCodes[0...4]),")
print(" \(caterhamCodes[5...9]),")
print(" \(caterhamCodes[10...14]).")
which prints:
Caterham has the following postcodes: [111, 111, 111, 111, 111],
[222, 222, 222, 222, 222],
[333, 333, 333, 333, 333].
Essentially, I need what I have above minus some square brackets and without the punctuation after each time a block of zip codes is printed. The book specifies that I might need to use a parameter called terminator. It also mentions I might need to learn how to represent special characters in string literals.
I appreciate that this is probably a high level question with a simple answer, but I'm only a few weeks into learning, so I hope I can be forgiven for asking at least a few silly questions!
Welcome to the developer community and have a nice stay!
I am trying to put answer as simple as possible, so here is my attempt:
var areaCodes = ["Caterham": [111, 111, 111, 111, 111],
"Coulsdon": [222, 222, 222, 222, 222],
"Purley": [333, 333, 333, 333, 333]]
let codesArray = areaCodes.values.sorted(by: { $0[0] < $1[0] })
let caterhamString = "Caterham has the following zip codes: ["
var printString = caterhamString
for (index, area) in codesArray.enumerated() {
for code in area {
printString += "\(code), "
}
if index != codesArray.count - 1 {
printString += "\n" + String(repeating: " ", count: caterhamString.count)
}
}
print(printString.dropLast(2).appending("]"))
Hope this helps! Good luck!
Here is a way of getting the desired output :
let intro = "Caterham has the following zip codes: ["
let spaces = ",\n" + String(repeating: " ", count: intro.count)
let areaCodes = ["Caterham": [111, 111, 111, 111, 111], "Coulsdon": [222, 222, 222, 222, 222], "Purley": [333, 333, 333, 333, 333]]
let codes = areaCodes.values.sorted { $0[0] < $1[0] }
var output = intro +
codes.map { $0.map{ String($0) }.joined(separator: ", ") }
.joined(separator: spaces)
+ "]"
print(output)
Which prints
Caterham has the following zip codes: [111, 111, 111, 111, 111,
222, 222, 222, 222, 222,
333, 333, 333, 333, 333]

Key must not contain . error in pymongo

I am trying to get the output of serverStatus command via pymongo and then insert it into a mongodb collection. Here is the dictionary
{u'metrics': {u'getLastError': {u'wtime': {u'num': 0, u'totalMillis': 0}, u'wtimeouts': 0L}, u'queryExecutor': {u'scanned': 0L}, u'record': {u'moves': 0L}, u'repl': {u'buffer': {u'count': 0L, u'sizeBytes': 0L, u'maxSizeBytes': 268435456}, u'apply': {u'batches': {u'num': 0, u'totalMillis': 0}, u'ops': 0L}, u'oplog': {u'insert': {u'num': 0, u'totalMillis': 0}, u'insertBytes': 0L}, u'network': {u'bytes': 0L, u'readersCreated': 0L, u'getmores': {u'num': 0, u'totalMillis': 0}, u'ops': 0L}, u'preload': {u'docs': {u'num': 0, u'totalMillis': 0}, u'indexes': {u'num': 0, u'totalMillis': 0}}}, u'ttl': {u'passes': 108L, u'deletedDocuments': 0L}, u'operation': {u'fastmod': 0L, u'scanAndOrder': 0L, u'idhack': 0L}, u'document': {u'deleted': 0L, u'updated': 0L, u'inserted': 1L, u'returned': 0L}}, u'process': u'mongod', u'pid': 7073, u'connections': {u'current': 1, u'available': 818, u'totalCreated': 58L}, u'locks': {u'admin': {u'timeAcquiringMicros': {}, u'timeLockedMicros': {}}, u'local': {u'timeAcquiringMicros': {u'r': 1942L, u'w': 0L}, u'timeLockedMicros': {u'r': 72369L, u'w': 0L}}, u'.': {u'timeAcquiringMicros': {u'R': 218733L, u'W': 30803L}, u'timeLockedMicros': {u'R': 311478L, u'W': 145679L}}}, u'cursors': {u'clientCursors_size': 0, u'timedOut': 0, u'totalOpen': 0}, u'globalLock': {u'totalTime': 6517358000L, u'lockTime': 145679L, u'currentQueue': {u'total': 0, u'writers': 0, u'readers': 0}, u'activeClients': {u'total': 0, u'writers': 0, u'readers': 0}}, u'extra_info': {u'note': u'fields vary by platform', u'page_faults': 21, u'heap_usage_bytes': 62271152}, u'uptime': 6518.0, u'network': {u'numRequests': 103, u'bytesOut': 106329, u'bytesIn': 6531}, u'uptimeMillis': 6517358L, u'recordStats': {u'local': {u'pageFaultExceptionsThrown': 0, u'accessesNotInMemory': 0}, u'pageFaultExceptionsThrown': 0, u'accessesNotInMemory': 0}, u'version': u'2.4.8', u'dur': {u'compression': 0.0, u'journaledMB': 0.0, u'commits': 30, u'writeToDataFilesMB': 0.0, u'commitsInWriteLock': 0, u'earlyCommits': 0, u'timeMs': {u'writeToJournal': 0, u'dt': 3077, u'remapPrivateView': 0, u'prepLogBuffer': 0, u'writeToDataFiles': 0}}, u'mem': {u'resident': 36, u'supported': True, u'virtual': 376, u'mappedWithJournal': 160, u'mapped': 80, u'bits': 64}, u'opcountersRepl': {u'getmore': 0, u'insert': 0, u'update': 0, u'command': 0, u'query': 0, u'delete': 0}, u'indexCounters': {u'missRatio': 0.0, u'resets': 0, u'hits': 0, u'misses': 0, u'accesses': 0}, u'uptimeEstimate': 6352.0, u'host': u'kal-el', u'writeBacksQueued': False, u'localTime': datetime.datetime(2014, 1, 18, 8, 1, 30, 22000), u'backgroundFlushing': {u'last_finished': datetime.datetime(2014, 1, 18, 8, 0, 52, 713000), u'last_ms': 0, u'flushes': 108, u'average_ms': 1.1111111111111112, u'total_ms': 120}, u'opcounters': {u'getmore': 0, u'insert': 1, u'update': 0, u'command': 105, u'query': 108, u'delete': 0}, u'ok': 1.0, u'asserts': {u'msg': 0, u'rollovers': 0, u'regular': 0, u'warning': 0, u'user': 0}}
I am getting "Key '.' must not contain ." error. What could be the issue here? I am not seeing any . in the key name.
Here is the traceback:
Traceback (most recent call last):
File "src/mongodb_status.py", line 37, in <module>
get_mongodb_status()
File "src/mongodb_status.py", line 23, in get_mongodb_status
md_status.insert(status_data)
File "/home/guruprasad/dev/py/src/dnacraft_monitor_servers/venv/local/lib/python2.7/site-packages/pymongo/collection.py", line 362, in insert
self.database.connection)
bson.errors.InvalidDocument: key '.' must not contain '.'
In the 14th line:
u'.': {u'timeAcquiringMicros': {u'R': 218733L, u'W': 30803L}, u'timeLockedMicros': {u'R': 311478L, u'W': 145679L}}}
For future safety, iterate through the keys, replace '.'s with '_' or something, and then perform a write.
Here is a function which will remove '.' from your keys:
def fix_dict(data, ignore_duplicate_key=True):
"""
Removes dots "." from keys, as mongo doesn't like that.
If the key is already there without the dot, the dot-value get's lost.
This modifies the existing dict!
:param ignore_duplicate_key: True: if the replacement key is already in the dict, now the dot-key value will be ignored.
False: raise ValueError in that case.
"""
if isinstance(data, (list, tuple)):
list2 = list()
for e in data:
list2.append(fix_dict(e))
# end if
return list2
if isinstance(data, dict):
# end if
for key, value in data.items():
value = fix_dict(value)
old_key = key
if "." in key:
key = old_key.replace(".", "")
if key not in data:
data[key] = value
else:
error_msg = "Dict key {key} containing a \".\" was ignored, as {replacement} already exists".format(
key=key_old, replacement=key)
if force:
import warnings
warnings.warn(error_msg, category=RuntimeWarning)
else:
raise ValueError(error_msg)
# end if
# end if
del data[old_key]
# end if
data[key] = value
# end for
return data
# end if
return data
# end def
A solution that worked for me was to wrap the dictionary inside a python list:
new_item_to_store = list(dict_to_store.items())
An interesting point is that the keys through the dot are not saved for insert_one
And if you save the object, and then update it via find_one_and_update, the keys through the dot will not throw an error
Error:
product = {'name': 'test_product', 'links': {'test.xyz': 'https://...'}}
product_id = products_collection.insert_one(product).inserted_id
Working version:
product = {'name': 'test_product', 'links': {}}
product_id = self.products_collection.insert_one(product).inserted_id
products_collection.find_one_and_update(
{'_id': product_id},
{'$set': {'links': {'test.xyz': 'https://...'}}}
)

Error in XML Error Domain=NSXMLParserErrorDomain Code=39?

I have following xml
<?xml version='1.0' encoding='UTF-8'?>
<businesses>
<business>
<businessCount>1</businessCount>
<dealsCount>3</dealsCount>
<city>asdf</city>
<state>asdf</state>
<country>akdsjfasdf</country>
<latitude></latitude>
<longitude></longitude>
</business>
<business>
<businessCount>1</businessCount>
<dealsCount>1</dealsCount>
<city>karachi</city>
<state>sindg</state>
<country>Pakistan</country>
<latitude>24.8567436</latitude>
<longitude>66.8734836</longitude>
</business>
<business>
<businessCount>1</businessCount>
<dealsCount>2</dealsCount>
<city>karachi</city>
<state>sindh</state>
<country>pakistan</country>
<latitude>24.893379</latitude>
<longitude>67.028061</longitude>
</business>
</businesses>
but getting the following error while parsing
Error Domain=NSXMLParserErrorDomain Code=39 "The operation couldn’t be completed. (NSXMLParserErrorDomain error 39.)"
I read the documentation and also varify the syntax of XML, but didn't find what issue is with it.
Can anyone give any idea or help?
check these error code in apple documentation
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html
enum {
NSXMLParserInternalError = 1,
NSXMLParserOutOfMemoryError = 2,
NSXMLParserDocumentStartError = 3,
NSXMLParserEmptyDocumentError = 4,
NSXMLParserPrematureDocumentEndError = 5,
NSXMLParserInvalidHexCharacterRefError = 6,
NSXMLParserInvalidDecimalCharacterRefError = 7,
NSXMLParserInvalidCharacterRefError = 8,
NSXMLParserInvalidCharacterError = 9,
NSXMLParserCharacterRefAtEOFError = 10,
NSXMLParserCharacterRefInPrologError = 11,
NSXMLParserCharacterRefInEpilogError = 12,
NSXMLParserCharacterRefInDTDError = 13,
NSXMLParserEntityRefAtEOFError = 14,
NSXMLParserEntityRefInPrologError = 15,
NSXMLParserEntityRefInEpilogError = 16,
NSXMLParserEntityRefInDTDError = 17,
NSXMLParserParsedEntityRefAtEOFError = 18,
NSXMLParserParsedEntityRefInPrologError = 19,
NSXMLParserParsedEntityRefInEpilogError = 20,
NSXMLParserParsedEntityRefInInternalSubsetError = 21,
NSXMLParserEntityReferenceWithoutNameError = 22,
NSXMLParserEntityReferenceMissingSemiError = 23,
NSXMLParserParsedEntityRefNoNameError = 24,
NSXMLParserParsedEntityRefMissingSemiError = 25,
NSXMLParserUndeclaredEntityError = 26,
NSXMLParserUnparsedEntityError = 28,
NSXMLParserEntityIsExternalError = 29,
NSXMLParserEntityIsParameterError = 30,
NSXMLParserUnknownEncodingError = 31,
NSXMLParserEncodingNotSupportedError = 32,
NSXMLParserStringNotStartedError = 33,
NSXMLParserStringNotClosedError = 34,
NSXMLParserNamespaceDeclarationError = 35,
NSXMLParserEntityNotStartedError = 36,
NSXMLParserEntityNotFinishedError = 37,
NSXMLParserLessThanSymbolInAttributeError = 38,
NSXMLParserAttributeNotStartedError = 39,
NSXMLParserAttributeNotFinishedError = 40,
NSXMLParserAttributeHasNoValueError = 41,
NSXMLParserAttributeRedefinedError = 42,
NSXMLParserLiteralNotStartedError = 43,
NSXMLParserLiteralNotFinishedError = 44,
NSXMLParserCommentNotFinishedError = 45,
NSXMLParserProcessingInstructionNotStartedError = 46,
NSXMLParserProcessingInstructionNotFinishedError = 47,
NSXMLParserNotationNotStartedError = 48,
NSXMLParserNotationNotFinishedError = 49,
NSXMLParserAttributeListNotStartedError = 50,
NSXMLParserAttributeListNotFinishedError = 51,
NSXMLParserMixedContentDeclNotStartedError = 52,
NSXMLParserMixedContentDeclNotFinishedError = 53,
NSXMLParserElementContentDeclNotStartedError = 54,
NSXMLParserElementContentDeclNotFinishedError = 55,
NSXMLParserXMLDeclNotStartedError = 56,
NSXMLParserXMLDeclNotFinishedError = 57,
NSXMLParserConditionalSectionNotStartedError = 58,
NSXMLParserConditionalSectionNotFinishedError = 59,
NSXMLParserExternalSubsetNotFinishedError = 60,
NSXMLParserDOCTYPEDeclNotFinishedError = 61,
NSXMLParserMisplacedCDATAEndStringError = 62,
NSXMLParserCDATANotFinishedError = 63,
NSXMLParserMisplacedXMLDeclarationError = 64,
NSXMLParserSpaceRequiredError = 65,
NSXMLParserSeparatorRequiredError = 66,
NSXMLParserNMTOKENRequiredError = 67,
NSXMLParserNAMERequiredError = 68,
NSXMLParserPCDATARequiredError = 69,
NSXMLParserURIRequiredError = 70,
NSXMLParserPublicIdentifierRequiredError = 71,
NSXMLParserLTRequiredError = 72,
NSXMLParserGTRequiredError = 73,
NSXMLParserLTSlashRequiredError = 74,
NSXMLParserEqualExpectedError = 75,
NSXMLParserTagNameMismatchError = 76,
NSXMLParserUnfinishedTagError = 77,
NSXMLParserStandaloneValueError = 78,
NSXMLParserInvalidEncodingNameError = 79,
NSXMLParserCommentContainsDoubleHyphenError = 80,
NSXMLParserInvalidEncodingError = 81,
NSXMLParserExternalStandaloneEntityError = 82,
NSXMLParserInvalidConditionalSectionError = 83,
NSXMLParserEntityValueRequiredError = 84,
NSXMLParserNotWellBalancedError = 85,
NSXMLParserExtraContentError = 86,
NSXMLParserInvalidCharacterInEntityError = 87,
NSXMLParserParsedEntityRefInInternalError = 88,
NSXMLParserEntityRefLoopError = 89,
NSXMLParserEntityBoundaryError = 90,
NSXMLParserInvalidURIError = 91,
NSXMLParserURIFragmentError = 92,
NSXMLParserNoDTDError = 94,
NSXMLParserDelegateAbortedParseError = 512
};
typedef NSInteger NSXMLParserError;```