1use std::ffi::CString;
20use std::str;
21
22use uuid::Uuid;
23
24use crate::connect::Connect;
25use crate::error::Error;
26
27#[derive(Debug)]
31pub struct Network {
32 ptr: Option<sys::virNetworkPtr>,
33}
34
35unsafe impl Send for Network {}
36unsafe impl Sync for Network {}
37
38impl Drop for Network {
39 fn drop(&mut self) {
40 if self.ptr.is_some() {
41 if let Err(e) = self.free() {
42 panic!("Unable to drop memory for Network: {e}")
43 }
44 }
45 }
46}
47
48impl Clone for Network {
49 fn clone(&self) -> Self {
57 self.add_ref().unwrap()
58 }
59}
60
61impl Network {
62 pub unsafe fn from_ptr(ptr: sys::virNetworkPtr) -> Network {
66 Network { ptr: Some(ptr) }
67 }
68
69 fn add_ref(&self) -> Result<Network, Error> {
70 unsafe {
71 if sys::virNetworkRef(self.as_ptr()) == -1 {
72 return Err(Error::last_error());
73 }
74 }
75
76 Ok(unsafe { Network::from_ptr(self.as_ptr()) })
77 }
78
79 pub fn as_ptr(&self) -> sys::virNetworkPtr {
80 self.ptr.unwrap()
81 }
82
83 pub fn get_connect(&self) -> Result<Connect, Error> {
84 let ptr = unsafe { sys::virNetworkGetConnect(self.as_ptr()) };
85 if ptr.is_null() {
86 return Err(Error::last_error());
87 }
88 Ok(unsafe { Connect::from_ptr(ptr) })
89 }
90
91 pub fn lookup_by_name(conn: &Connect, id: &str) -> Result<Network, Error> {
92 let id_buf = CString::new(id).unwrap();
93 let ptr = unsafe { sys::virNetworkLookupByName(conn.as_ptr(), id_buf.as_ptr()) };
94 if ptr.is_null() {
95 return Err(Error::last_error());
96 }
97 Ok(unsafe { Network::from_ptr(ptr) })
98 }
99
100 pub fn lookup_by_uuid(conn: &Connect, uuid: Uuid) -> Result<Network, Error> {
101 let ptr = unsafe { sys::virNetworkLookupByUUID(conn.as_ptr(), uuid.as_bytes().as_ptr()) };
102 if ptr.is_null() {
103 return Err(Error::last_error());
104 }
105 Ok(unsafe { Network::from_ptr(ptr) })
106 }
107
108 pub fn lookup_by_uuid_string(conn: &Connect, uuid: &str) -> Result<Network, Error> {
109 let uuid_buf = CString::new(uuid).unwrap();
110 let ptr = unsafe { sys::virNetworkLookupByUUIDString(conn.as_ptr(), uuid_buf.as_ptr()) };
111 if ptr.is_null() {
112 return Err(Error::last_error());
113 }
114 Ok(unsafe { Network::from_ptr(ptr) })
115 }
116
117 pub fn get_name(&self) -> Result<String, Error> {
118 let n = unsafe { sys::virNetworkGetName(self.as_ptr()) };
119 if n.is_null() {
120 return Err(Error::last_error());
121 }
122 Ok(unsafe { c_chars_to_string!(n, nofree) })
123 }
124
125 pub fn get_uuid(&self) -> Result<Uuid, Error> {
126 let mut uuid: [libc::c_uchar; sys::VIR_UUID_BUFLEN as usize] =
127 [0; sys::VIR_UUID_BUFLEN as usize];
128 let ret = unsafe { sys::virNetworkGetUUID(self.as_ptr(), uuid.as_mut_ptr()) };
129 if ret == -1 {
130 return Err(Error::last_error());
131 }
132 Ok(Uuid::from_bytes(uuid))
133 }
134
135 pub fn get_uuid_string(&self) -> Result<String, Error> {
136 let mut uuid: [libc::c_char; sys::VIR_UUID_STRING_BUFLEN as usize] =
137 [0; sys::VIR_UUID_STRING_BUFLEN as usize];
138 let ret = unsafe { sys::virNetworkGetUUIDString(self.as_ptr(), uuid.as_mut_ptr()) };
139 if ret == -1 {
140 return Err(Error::last_error());
141 }
142 Ok(unsafe { c_chars_to_string!(uuid.as_ptr(), nofree) })
143 }
144
145 pub fn get_bridge_name(&self) -> Result<String, Error> {
146 let n = unsafe { sys::virNetworkGetBridgeName(self.as_ptr()) };
147 if n.is_null() {
148 return Err(Error::last_error());
149 }
150 Ok(unsafe { c_chars_to_string!(n) })
151 }
152
153 pub fn get_xml_desc(&self, flags: sys::virNetworkXMLFlags) -> Result<String, Error> {
154 let xml = unsafe { sys::virNetworkGetXMLDesc(self.as_ptr(), flags) };
155 if xml.is_null() {
156 return Err(Error::last_error());
157 }
158 Ok(unsafe { c_chars_to_string!(xml) })
159 }
160
161 pub fn create(&self) -> Result<u32, Error> {
162 let ret = unsafe { sys::virNetworkCreate(self.as_ptr()) };
163 if ret == -1 {
164 return Err(Error::last_error());
165 }
166 Ok(ret as u32)
167 }
168
169 pub fn define_xml(conn: &Connect, xml: &str) -> Result<Network, Error> {
170 let xml_buf = CString::new(xml).unwrap();
171 let ptr = unsafe { sys::virNetworkDefineXML(conn.as_ptr(), xml_buf.as_ptr()) };
172 if ptr.is_null() {
173 return Err(Error::last_error());
174 }
175 Ok(unsafe { Network::from_ptr(ptr) })
176 }
177
178 pub fn create_xml(conn: &Connect, xml: &str) -> Result<Network, Error> {
179 let xml_buf = CString::new(xml).unwrap();
180 let ptr = unsafe { sys::virNetworkCreateXML(conn.as_ptr(), xml_buf.as_ptr()) };
181 if ptr.is_null() {
182 return Err(Error::last_error());
183 }
184 Ok(unsafe { Network::from_ptr(ptr) })
185 }
186
187 pub fn destroy(&self) -> Result<(), Error> {
188 let ret = unsafe { sys::virNetworkDestroy(self.as_ptr()) };
189 if ret == -1 {
190 return Err(Error::last_error());
191 }
192 Ok(())
193 }
194
195 pub fn undefine(&self) -> Result<(), Error> {
196 let ret = unsafe { sys::virNetworkUndefine(self.as_ptr()) };
197 if ret == -1 {
198 return Err(Error::last_error());
199 }
200 Ok(())
201 }
202
203 pub fn free(&mut self) -> Result<(), Error> {
204 let ret = unsafe { sys::virNetworkFree(self.as_ptr()) };
205 if ret == -1 {
206 return Err(Error::last_error());
207 }
208 self.ptr = None;
209 Ok(())
210 }
211
212 pub fn is_active(&self) -> Result<bool, Error> {
213 let ret = unsafe { sys::virNetworkIsActive(self.as_ptr()) };
214 if ret == -1 {
215 return Err(Error::last_error());
216 }
217 Ok(ret == 1)
218 }
219
220 pub fn is_persistent(&self) -> Result<bool, Error> {
221 let ret = unsafe { sys::virNetworkIsPersistent(self.as_ptr()) };
222 if ret == -1 {
223 return Err(Error::last_error());
224 }
225 Ok(ret == 1)
226 }
227
228 pub fn get_autostart(&self) -> Result<bool, Error> {
229 let mut auto = 0;
230 let ret = unsafe { sys::virNetworkGetAutostart(self.as_ptr(), &mut auto) };
231 if ret == -1 {
232 return Err(Error::last_error());
233 }
234 Ok(auto == 1)
235 }
236
237 pub fn set_autostart(&self, autostart: bool) -> Result<u32, Error> {
238 let ret = unsafe { sys::virNetworkSetAutostart(self.as_ptr(), autostart as libc::c_int) };
239 if ret == -1 {
240 return Err(Error::last_error());
241 }
242 Ok(ret as u32)
243 }
244
245 pub fn update(
246 &self,
247 cmd: sys::virNetworkUpdateCommand,
248 section: sys::virNetworkUpdateSection,
249 index: i32,
250 xml: &str,
251 flags: sys::virNetworkUpdateFlags,
252 ) -> Result<(), Error> {
253 let xml_buf = CString::new(xml).unwrap();
254 let ret = unsafe {
255 sys::virNetworkUpdate(
256 self.as_ptr(),
257 cmd,
258 section,
259 index as libc::c_int,
260 xml_buf.as_ptr(),
261 flags,
262 )
263 };
264 if ret == -1 {
265 return Err(Error::last_error());
266 }
267 Ok(())
268 }
269}